i am building simple dapp application where i want to verify something and then only make contract interaction but right now i am struggling to put a middleware which will act like user will make txn through metamask and then this txn or something will go to backend server on any language probably node js , and i will do some checking and if all good then Send it to block chain.
Any suggestion?
Right now its all in react Frontend and metamask browser extension.. and i can not make client side code restricted
And i can not ask for private key even.
Not possible by design. A transaction needs to be signed by the sender's private key. So unless the users are willing to give you their private key (so that you could sign the transaction for them on the backend), you'll need to change your approach.
If you need to allow interaction with the contract only to users authorized by your app, the contract needs to hold the list of authorized addresses. And the list can be updated by your app (that holds the private key to the owner address). Example:
pragma solidity ^0.8;
contract MyContract {
address public owner = address(0x123);
mapping(address => bool) public isAuthorized;
function setAuthorized(address _address, bool _isAuthorized) external {
require(msg.sender == owner, 'Only the contract owner can set authorized addresses');
isAuthorized[_address] = _isAuthorized;
}
function foo() external {
require(isAuthorized[msg.sender], 'Only authorized addresses can execute this function');
// ...
}
}
Related
with my own 0x363.. wallet address
I am generating erc20 token and when I issue this erc20 contract a contract address is generated (0x966D...). that is, I have one wallet address and one coin address.
E.g:
1 mytoken = 1 ethereum
E.g:
If a user buys my token with metamask, the user will pay ethereum.
And where is 1 ethereum. Why is this ethereum not uploaded to my admin account (0x363..). this ethereum goes to erc20 (0x966D ..) as far as I understand. How can I get this ethereum to my admin account?
How can I get this ethereum to my admin account?
Based on the context of the question (the ETH is paid to the token contract - not to a DEX pair contract), I'm assuming you have a custom buy function.
You can expand this buy function to use the transfer() method of address payable to transfer the just received ETH to your admin address.
pragma solidity ^0.8;
contract MyToken {
address admin = address(0x123);
function buy() external payable {
// transfers the whole ETH `value` sent to the `buy()` function
// to the `admin` address
payable(admin).transfer(msg.value);
// ... rest of your code
}
}
Contract bytecode is immutable (with some edge case exceptions), so in order to perform the change, you'll need to deploy a new contract - can't expand the already deployed contract.
Are you familiar with ethereum and web3js-api in node js?
I used the framework sails, and i am a little bit confused how to generate a new account like (https://www.myetherwallet.com/). For now i used web3js-api v.1.0.0. I can get current account and balance. i try to create new account, but it return error, says create is not a function, etc.
i used testnet, how can i connect it to metamask (Rinkeby Network)? So if i generate new account, the account will appear in metamask account list also.
If you know, please share.
Thanks.
You can use this package :
https://www.npmjs.com/package/node-ethereum-wallet
let myWallet = new EthereumWallet() // using MyEtherAPI.com web3 HTTP provider
In its simplest form, Ethereum wallet is just a single private key.
Generate a random 256-bit integer - this is your private key
web3.js functions can import any private key with privateKeyToAccount - This will derive an Ethereum public key and Ethereum address, which is just trimmed public key, for you
Now web3.js can use your private key to sign transactions and messages
I'm developing a quiz app which requires authorization for only-subscribed members can see.
How to do that? I'm thinking of putting metadata (is_subscribed) to true for subscribed member and give the scope so he/she can gain permissions.
But, I don't know how to do it. Please help. The docs is so confusing
There are two separate concerns here.
Where to keep the subscription information. app_metadata is fine, or you might choose to do so in a backend database (application specific). A client application will probably handle subscriptions and be in charge of updating that value. If you store the value in app_metadata, you will use Management API v2 to alter the user profile from the application that handles subscriptions.
Add an authorization scope based on the subscription status. In this case, you would use a rule to add a custom scope based on the value of the is_subscribed field. I.e.:
function(user, context, callback) {
if (user.app_metadata && user.app_metadata.is_subscribed) {
context.accessToken.scope = ['read:quiz'];
} else {
// remove the ability to read a quiz if not subscribed.
context.accessToken.scope = [];
}
callback(null, user, context);
}
If you decided to store the subscription information in a backend database instead of in the app_metadata, you would simply access the database from the rule in the above code.
I'am running a nodejs/express application as a backend solution for my current project. The application is using passport-jwt to secure some routes with JWT as header Authorization for a route, let's call this route secure-route. Now I'm running a second application which needs to access secure-route without the necessary Authorization header. The necessary Authorization header is generated by a login route after the user has authorized successfully.
The problem is, that I don't want to provide a (fake) jwt Authorization header (which shouldn't expire). The second application/server should access my first application with a more appropriate authorization strategy like basic-auth.
I thought about making secure-route private in another router module so I can access this private route by maybe rerouting.
So how can I make an express route private accessible ? Or is there a solution for authenticating a backend/server without affecting the current authentication strategy ?
EDIT :
both backends running on a serverless structure on AWS
Assuming this second application you mention is running either on the same server or on another server in the same network, then you can do the following:
Create a new web server on a non-standard port that is not accessible from the general internet (just a few lines of code with Express).
Run that new web server in the same nodejs process that your existing server with the secure-route is running on.
In that new server, create a route for the private access. In that private route, do not implement any access control.
Put the code for the route into a separately callable function.
When that new server route gets hit, call the same function that you use to implement the secure route in the other server.
Verify that there is no access to your second server's port from the internet (firewall settings).
You could also just take your one existing server and route and allow access without the authorization header only when accessed from a specific IP address where your other app is running.
If you can't use anything about the network topology of the server to securely identify your 2nd app when it makes a request, then you have to create a secret credential for it and use that credential (akin to an admin password or admin certificate). Or, switch to an architecture where you can use the network topology to identify the 2nd app.
You should make a middleware and use it like this
/Starting Point of the Project/
let CONGIG = require('./config');
let middleware = require('./middleware');
let app = express();
app.use(middleware.testFunction);
require('./route')(app);
'use strict';
let middleware = {
testFunction : function(req,res,next){
var condition = ''; /* now here you can write your logic on condition that when should be the condition be true and when it shoudld not be true based on the req.url , if the user is trying to access any public url you can simply allow the true part of the condition to run and if the person is accessing a private part of route then you can check for additional parameters in header and then set the condition true and if not you must send an error msg or a simple message as you are not allowed to access the private parts of the web application. */
if(condtion){
next();
} else {
res.send('error');
}
}
}
So by designing a middlware you can basically seperate the logic of private and public routes and on what condition a route is public or private in a seperate module that will deal with it , it is little bit difficult to understand but it is better to first filter out public and private route than latter checking . In this way on the very initial hit we can differentiate the private and public routes.
I have a couple of self-hosted windows services running with ServiceStack. These services are used by a bunch of WPF and WinForms client applications.
I have written my own CredentialsAuthProvider. My first implementation of the user database was on MSSQL server using NHibernate. Now since the system is growing I reorganize things a bit. I have created a central 'infrastructue' service which uses Redis as data store and is responsible for account management, central configuration and preferences management. Later it will also contain central logging and RedisMQ. All accounts, roles etc are now stored there (instead of MSSQL). Account migration was successfuly and authentication works fine so far.
Now I have the problem, that clients and servers need to get and set their configurations / preferences. This means that my servers are also clients since they not only serve client requests for their specific business domain but itself need to call the 'infrastructure' server to load / update its own configuration and later log entries and messages.
To authenticate such requests I thought an API key is a good way to go. These requests are not user related and therefore do not need a gateway functionality, they simply need some communication with the central infrastructure server. So I was reading the ServiceStack docs about the API Key Provider, but unfortunately for me a lot remains unclear.
Here first some relevant code from my 'infrastructure' server's Configure method:
private PooledRedisClientManager RedisBusinessPool { get; set; }
//...
container.Register<IRedisClientsManager>(c => new PooledRedisClientManager(connStrBus));
container.Register(c => new AppUserRepository(RedisBusinessPool));
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new BediCredentialsAuthProvider(),
}
));
// For the API keys I tried:
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new ApiKeyAuthProvider(AppSettings)
{
KeyTypes = new []{"secret", "publishable"},
},
}
));
Since I enabled the API Key plugin I get an error on the client when I try to login:
ERROR; AccountManagerWinDesktop; [LoginViewModel+<Login>d__50.MoveNext]; - <username> failed to login to server <myInfrastructureServer>. Exception: 404 NotFound
Code: NotFound, Message: No configuration was added for OAuth provider 'credentials'
Does this mean, that I have to implement my own ApiKeyProvider to cooperate with my implementation of the CredentialAuthProvider? If so, what do I need to add?
In my CredentialAuthProvider implementation I have overwritten Logout, Authenticate, OnAuthenticated and TryAuthenticate. A WPF client offers a UI to store users and roles. They are stored on the Redis database including hashed passwords etc. In my TryAuthenticate implementation I simply have:
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
AppUser user = null;
try
{
//the repository handles all Redis database access
var userRepo = HostContext.TryResolve<AppUserRepository>();
user = userRepo.GetAppUser(userName);
if (user == null)
throw HttpError.NotFound("User '{0}' not found. Please try again.".Fmt(userName));
authService.Request.Items.Add("AppUser", user);
var pwdMgr = new PwdManager();
var hpwd = pwdMgr.GetHashedPassword(password, user.Salt);
if (hpwd == user.Password)
{
//do stuff
}
else
{
// do other stuff
}
return hpwd == user.Password;
}
catch (Exception ex)
{
Log.Error($"Error retrieving user {user} to authenticate. Error: {ex}");
throw;
}
}
What I do not understand right now - Questions:
How are API keys related to my own implementation of CredentialsAuthProvider?
How can I issue API keys to an application server? (I read that ServiceStack creates keys automatically when a user is created, but I do not need this in my scenario)
Do I also have to implement my own ApiKeyAuthProvidersimilar to the CredentialsAuthProvider I have overwritten? If so, is there a sample somewhere?
Is there any object / data model for API keys?
Do I need to implement something like the TryAuthenticate method above to verify my API Keys?
You should only ever register 1 of any Plugin type, so change your AuthFeature plugin to register all Auth Providers you want to enable, e.g:
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new BediCredentialsAuthProvider(),
new ApiKeyAuthProvider(AppSettings)
{
KeyTypes = new []{"secret", "publishable"},
},
}
));
How are API keys related to my own implementation of CredentialsAuthProvider?
An API Key is assigned to a User, i.e. when a request is received with an API Key, they're authenticated as the user the API Key is assigned to. API Keys are created for each new user that's registered, the above configuration creates a secret and publishable key for a new register created with the /register service.
API Keys requires using a User Auth Repository
Your users need to be persisted in an AuthRepository in order to use the API Key AuthProvider. The list of support Auth Repositories are listed on in the documentation. Although you can use your own custom User Auth Repository if it implements IUserAuthRepository and IManableApiKeys interfaces.
How can I issue API keys to an application server? (I read that ServiceStack creates keys automatically when a user is created, but I do not need this in my scenario)
An API Key is assigned to a User - all of ServiceStack AuthProviders revolves around Authenticating Users. One idea is to create a "User" to represent that App Server. You can use the IManageApiKeys API to create your own API Keys, there's an example of using this in the code-snippet for creating API Keys for existing Users.
Do I also have to implement my own ApiKeyAuthProvider similar to the CredentialsAuthProvider I have overwritten? If so, is there a sample somewhere?
You wont need to implement anything to use the existing ApiKeyAuthProvider but if it doesn't do what you need you can take ApiKeyAuthProvider.cs and create a customized version that does what you need.
Is there any object / data model for API keys?
The ApiKey class is the model that contains the API Key itself, which is persisted in all supported Auth Repositories.
Do I need to implement something like the TryAuthenticate method above to verify my API Keys?
No.