Should JWTs be used for more than just authenticating a user? I read that it's okay to store non sensitive stuff like a user ID in it. Would it be okay to store stuff like permission levels in the token? This way I get to avoid doing a database call.
JWT tokens can be used for authentication purposes, but nothing stops you from creating your own claims to store additional data, such as the user roles or a scope of access.
Some authentication providers add a scope of access to their tokens. Have a look at this answer.
Related
I'm trying to tweet on behalf of Twitter user using How to connect to endpoints using OAuth 2.0 Authorization Code Flow with PKCE.
A refresh token allows an application to obtain a new access token without prompting the user.
In order to post on behalf of the users when they are offline I assume the app needs to store this refresh token that Twitter gives it in the database to persist.
But is there a best practice for storing these tokens? I'm using mongodb.
I found this:
The recommended approach is not to store access tokens, but get the
access tokens as needed. Securely store only the refresh tokens, with
as much rigor as if they were access tokens.
-src
But the instruction that followed seemed to be specific to Azure.
How would you store a refresh token with rigor? What does that mean for mongodb?
I think this is a bit of an opinionated question. My answer here is more notes than a good answer
But here's the opinions I found so far from different devs and how to handle them.
Encrypting the refresh token is overkill
I think that quote was for a different use case of oauth2. Maybe for using oauth2 also as a login to your app you would have to be more careful with the refresh tokens, though I'm not sure.
But for my use case it seems ok to store the refresh token in the db unencrypted.
A hacker would need to steal the refresh token AND the client secret to get an access token. The client secret is stored in an env file. So the refresh token alone wouldn't allow a hacker to do anything with it.
You should encrypt the refresh token
Yes, a hacker would need to steal the refresh token AND the client secret to get an access token. But if they came that far, they could use the client secret to ask for more rights and take over the users twitter accounts. So there may be some motivation for a hacker to do that- if they realize they could take over thousands of twitter users accounts. I'm not really sure how you would encrypt the keys for mongo, maybe there is something similar to azure vault or maybe you can use vault with mongo.
Rebuttal to #2: If your env is secure, which it should be, you don't have to worry about your client secret getting compromised.
So my take away is this is sort of opinionated
I read something like this:
1-Once a user logs in, you can generate a token and store it in MySQL database and share the same token with the response of login API.
2-Store the token using shared-preferences.
3-When a user opens the app, check if the token exists if it does, then send the token with all the APIs inside the request header which requires the user to be logged in.
But what is the point of using token if i was keeping it in database.Eventually this token related with userid and with this userid everthing can be reachable.So I want to ask why should I use some token to keep user loged in instead of user email or something.
Using token is much more secure and useable. Storing just token more secure becase in case of leak, the token can be revoked or something. On the other side storing user's username and password is security risk. Also, most of the services use tokens on their API's and there is no username+pass authorization. For example whole OAuth2 concept is built on top of this. In short, tokens are much more secure and flexible.
Optimal usage of bearer token using as a set with an access token and refresh token. While you are passing access token on header while you are making HTTP request typically access token dies frequently especially when security is a prominent feature of the app, like banking apps. When a user makes an HTTP request and if the access token is dead then you should refresh it via another API call with the refresh token and return the same API call with the new access token.
Im thinking of using Auth0 for my API and web application and have a query . When the Jwt token is generated I would like to include some custom user claims that only exist in my user database. Is this possible or do all claims need to exist as pre-defined attributes in Auth0.
I have my own user database because there are some dynamic and complicated user permissions that I need to store there. I realize that one option is not to store these permissions in the token and I could have a separate api to get them but for performance and simplicity I'd rather wrap them into the Jwt token. I can't seem to see a way to do this.
Thanks in advance
You can do that using Rules and Custom Claims, and they don't have to be predefined or even persistent in a user profile.
See
https://auth0.com/docs/scopes/current/custom-claims
https://auth0.com/docs/api-auth/tutorials/adoption/scope-custom-claims
for docs and examples.
I've been developing my first REST API to serve as the back-end for a mobile application. I'm pulling info from different resources, and am a little confused when it comes to the token implementation (I'm using JWT).
The access token is used to ensure that the requester has access to the resource that is being called. My understanding is that I will then encode the user details in the ID Token, such that the relevant information can be returned. The refresh token is used as a security mechanism, to keep the user authenticated after the short-lived ID and access tokens expire.
The access token seems a little redundant, and maybe it is an interchangeable term for ID token? Can I just remove that part from my authentication scheme?
In the proposed scheme access and ID tokens are used interchangeably and do not provide any value over the other. All information provided in the access token can be stored in the ID token, or vice versa. The entire authentication scheme will then simply consist of an access token (containing both info on access permissions, and user info), and a refresh token (ensuring that users don't need to login again every t minutes).
I really want to use JWT for API access, to keep it stateless. But at the same time I need to have strong security recourse to deny tokens that are yet to expire.
For more sensitive user information APIs I can rely on forcing a fresh login, comparing the IP address, etc. But I still want to be able to revoke a users token if needed. I don't mind paying the overhead price.
What I imagined would be to have each user create their own secret key based on their password, and store it in the session. I don't mind trading the overhead for an easier way to deal with stolen tokens. This way a simple password reset should invalidate old tokens.
Acknowledging the trade off, does this method make sense? Are there better ways to go about this?
You should create a "blacklist" on your server. If a token needs to be revoked, place it in the blacklist and set it to expire from the list when the token expires. For every authentication attempt, you will verify that the incoming JWT is not in the blacklist. Redis can make this quite easy.
Alternatively, consider a third-party service such as Stormpath. Disclaimer: I work for Stormpath. We have an Oauth2 api that let's you issue access + refresh tokens (for a password grant flow). We handle revocation for you, so long as you don't mind the overhead of the REST call to verify the state of the token. Please see Using Stormpath for OAuth 2.0 and Access/Refresh Token Management. We have easy support for this in our Express-Stormpath .library
well, i just had the same kind of implementation. add hashed password to token, and when client returns the token, during validation, check if user's password has been changed in db, if user's hashed pass is not the same as the one you put in token, reject the token. In this way, you don't need to keep any info about user and/or token on the server.
I don't like the idea of white/black listing tokens, so I ended up using the users hashed password + another random key as their token's secret key:
+---------------+------------------------------------+-----------+
| email | password | key |
+---------------+------------------------------------+-----------+
| user#mail.com | asfsifj2fij4f4f4f8d9dfhs.8f8fhsd8h | r4nd0Mk3Y |
+---------------+------------------------------------+-----------+
I then keep a cache in memory of users id=>password+key to verify each users token. This way tokens can be discarded when: 1) user resets password; 2) application changes the user key.
This almost defeats the purpose of JWT's, but I need this layer of security for my use case.
JSON Web Token
JSON Web Token (JWT) is defined by the RFC 7519.
It's a standard method for representing claims securely between two parties. JWT is a self-contained token and enables you to store a user identifier, an expiration date and whatever you want (but don't store passwords) in a payload, which is a JSON encoded as Base64.
The payload can be read by the client and the integrity of the token can be easily checked by verifying its signature on the server.
Tracking your tokens
You won't need to persist JWT tokens if you don't need to track them.
Althought, by persisting the tokens, you will have the possibility of invalidating and revoking the access of them. To keep the track of JWT tokens, instead of persisting the whole token, you could persist the token identifier (the jti claim) and some metadata (the user you issued the token for, the expiration date, etc) if you need.
Your application can provide some functionality to revoke the tokens, but always consider revoking the tokens when the users change their password.
When persisting tokens, always consider removing the old ones in order to prevent your database from growing indefinitely.
Additional information
When sending sensitive data over the wire, your best friend is HTTPS and it protects your application against the man-in-the-middle attack.
To find some great resources to work with JWT, have a look at http://jwt.io.