I am creating routes in node js . I am creating routes for dashboard.
User login and get the JWT token.
By sending Token,User can access some route related to user(edit,delete,logout route etc).
But For admin, I want to create the routes which can see the list of users,edit or remove users,check the logout time of users.I have also set the flag in table to identify the person is user or Admin.
How will be authenticate routes for Admins on backend side?
You can be inspired by this logic, And no further explanation can be given here. follow steps (It may help):
First) define role field into DB mongoDB or Mysql (for example):
enum: ['user', 'admin']
Second) create a function checkRole(role) for check role after signin and verify jwt, then get user
Third) create separate route for admin panel (for example):
router.route('/admin-panel').use(authController.checkRole('admin'))
You can put your authorization flag in your JWT. When a user logs in, your server generates corresponding JWT, in which included authentication info(i.e. userId). You can put additional authorization info in the token(i.e. auth).
Based on the auth field, your server can identify whether the request is sent by a general user or an admin. Of course, securing the JWT from hijacking is an another story.
Related
To provide dynamic content delivery, I am using rewrites in fire base hosting. Whenever open website with index.html then the browser request the firebase cloud function main.
"rewrites": [ {
"source": "/index.html",
"function":"main"
}]
Now I am facing a problem to provide dynamic content based on user login status. I also checked about client side authendication using JS.
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
I don't know about web development. Here I have few questions,
How can I find authentication status of user by more flexible way? Does cookies used for this? I am asking because I don't know to pass firebase-token to the cloud function main.
Please address me an idea. Thank you all.
Short answer: End users don't have a sign-in status that's visible on a backend. That's just not how Firebase Authentication works.
Auth clients provide credentials to get a token that's used to identify themself when they invoke backend services. This tokens has a lifetime of 1 hour, and the client must refresh it in order to keep using it. Your backend doesn't know or care if the client has an auth token, if they use it, or if they refresh it. The client just needs to provide that token from whatever device they have signed in so the backend can validate it. There is no way your backend can know if the client obtained a token - you just have to accept the one it is given. This means you're going to have to actually figure out how to pass that token and validate it with the Firebase Admin SDK, or use a callable type function using the Firebase Client SDK to send that token automatically.
I want to allow users to sign in/up via GitHub using firebase by clicking on the same button.
I create a new authentication for every user in the server side.
With the little piece of code, I'm able to detect if either the user is new or not:
const provider = new firebase.auth.GithubAuthProvider();
firebase.auth().signInWithPopup(provider).then((result) => {
if (result.additionalUserInfo.isNewUser) {
// The user is new
} else {
// The user is old
}
But, when the function signInWithPopup is called, if the user is a new user, a new authentication is automatically created for him. How can I avoid this?
And if the user is already authenticate, how can the user sign in from the client side? Where is the link between the authentication done from the back end with the user that wants to sign in the front end?
This is not how OAuth works. If you use an authentication provider like GitHub, they handle auth flow for you. The only thing that you are left with on the frontend side is an idToken with your identity, basic profile info, and a signature so you can as a user using this token. There's no distinction between sign up/sign in actions.
As you have noticed, Firebase is an extra layer in this flow, it creates an account for a user who signs in for the first time. But there's no user limit or extra payment so I wouldn't bother too much about these extra accounts. You might consider periodical cleanups if you care about the security here.
If you want to actually check if the user exists you have to use firebase-admin e.g. in a Firebase Function before the signInWithPopup is called. But still, unless you want to prevent users from signing up, you can hook your server logic into functions.auth.user().onCreate trigger.
To answer your last question, when the user is already signed in, you'll get the user object in firebase.auth().onAuthStateChanged when a page is loaded. Login state is stored by Firebase.js so once you have called signInWithPopup, you don't need extra steps.
Keystonejs has some kind of bug on the Admin UI login page:
While trying to access Keystone Admin UI, with User that Permissions isAdmin = false
In case login/pass is correct Keystonejs screen says: "You're already signed in."
There should be response something like: "You don't have permissions"
It's no too informative so I suggest to change it to something like "You don't have permissions".
So question: is it possible to change text of that message?
The issue is that you have logged in using valid credentials but have not granted that user access to the Admin UI. There is (as at Keystone 4.0.0) no default path for users without the canAccessKeystone permission. I believe the general assumption was that non-admin users should not be logging into Keystone admin, but authenticated sessions are still useful for API endpoints.
So question: is it possible to change text of that message?
I'm not aware of a straightforward way to only change this message, but if you're keen you could always modify the Keystone 4.0 source for your own requirements and submit a pull request to have this considered for merging into the project. I've created issue #4786 in Keystone's GitHub issue tracker to improve the messaging for users who successfully login but do not have access to the admin UI.
In the interim, one possible workaround would be to use the keystone signin redirect configuration to set a preferred entry point that can either handle all user types or redirect appropriately.
For example, you could add the following to your keystone.js config:
keystone.set('signin redirect', '/gohome')
The /gohome route could render a page or do a simple redirection based on user properties:
app.get('/gohome', function(req, res) {
var url = (req.user && req.user.canAccessKeystone) ? '/keystone' : '/user';
res.redirect(url);
});
I'm trying to keep things simple and using auth0-js WebAuth to authenticate users. However, as there is a redirect involved, I'm not in control of the sign-up functionality at that point.
My specific use-case is to call a createUser graphql mutation using Graphcool to create a user in my database, but I only want to do this if the user is a new user, obviously.
MY QUESTION: Using auth0-js, is it possible to identify if a user is a new or existing user in my client application after the redirect from Auth0 back to my client application (assuming authentication is successful)?
There are two general approaches here, and both require you to persist the Auth0 token in local storage after receiving it. You can use a middleware for your GraphQL client that checks local storage for a token for every request and includes it as the Authorization: Bearer <token> header if present.
Let's now look at the two approaches.
Always try to create the user
Trying to create the user using the createUser mutation as soon as receiving the token is a fairly simple approach. This is how the mutation looks like:
mutation signUp($token: String!) {
createUser(authProvider: {
auth0: {
idToken: $token
}
}) {
id
}
}
Now, if the token is valid and matches the configuration of the Auth0 integration in Graphcool, there are two possible scenarios. Note, a token corresponds to a user if the auth0UserId it embeds matches.
there is already a registered user corresponding to the token. In this case, a GraphQL error Code 3023: CannotSignUpUserWithCredentialsExist will be returned (compare with the error reference documentation). In your application you can catch this error to proceed normally.
there is no registered user yet corresponding to the token. The createUser mutation will return id and all is good!
Check if the user is already signed in
If you have a more elaborate sign up flow, you might want to redirect your users to a sign up form, which is not really possible with the first approach. Instead, we can check if the currently used token corresponds to a registered user before proceeding. You can use the user query to do that:
query {
user {
id
}
}
Again, there are the same two scenarios as above:
there is already a registered user corresponding to the token. In this case, a the query returns a user object with the corresponding user id. So we can proceed the flow in the app normally.
there is no registered user yet corresponding to the token. The date returned from the user query will be null, so we need to call the createUser mutation, or switch to a sign up form or similar.
Compare this to this FAQ article in the Graphcool documentation.
In that case, the simplest solution will be to use auth0 rule and use context.stats.loginsCount field to detect the user is new or not.
https://auth0.com/docs/rules/references/context-object
You can add context.stats.loginsCount field value as a custom claim in the token using rule. Therefore, in your application, you can make a HTTP request to /userinfo endpoint to get the token data.
function (user, context, callback) {
const count=context.stats.loginsCount;
context.idToken["http://mynamespace/logincounts"] = count;
callback(null, user, context);
}
https://auth0.com/docs/api-auth/tutorials/adoption/scope-custom-claims
If the counts are equal to 1, create the user in your DB.
I'm creating a web based application that requires people to register and login for access to certain pages.
I want to stop users from giving out their username/password to other people by denying access to more than one person using the same username at the
same time.
Don't know if its a great solution but you can keep a bit in users table and set it to 1 when user is logged in. And check it before login, if its set don't allow more logins by other users. On logout function unset this bit.
In spring security, we can able to manage user login like this,
<session-management>
<concurrency-control max-sessions="1"/>
</session-management>
So when the time user logged in, you will gonna set some session values, If one more user going to login using existing user logged in ID and password, before going to login condition, check those parameters in the back end. You can able to prevent user login from multiple times for the Same userLogin and Password.
You can use either database or distributed cache.
I prefer using database ( User_ID, SessionKey, LoginTime, Logout time)
After login, you have to record entry in database/cache with a unique session id. When login is attempted with same credentials, update existing entry with logout time and create new entry with recent login time
e.g. When you login with John,
the entry in table is like 'John','1020edf1','29-06-2015 00:10:00',null.
When second login comes after 10 minutes,
The entries in table will be like this
'John','1020edf1','29-06-2015 00:10:00','29-06-2015 00:20:00'
'John','10asdf21','29-06-2015 00:20:00','null'
Form your application, you can have reaper thread mechanism, which will remove inactive sessions if user tries to logout from the application.
Here session key is unique session id generated by application server.