I'm running a mock expressjs server in the back, and ember (ember-simple-auth) on the front with the ember-simple-auth-token addon. I'm using JWT tokens. I'm trying to decide whats the best way to send my user information. Usually when the user submits their credentials I create a new token, store a copy of it in the database (I'm using mongodb), send it to the frontend and then use the token to fetch information user information. I have a /auth/token (which authenticates and sends the token, makes a copy and stores it in the database) & /current_user route which gets called on the initial login, which uses the token and fetches the user info.
Is it better to simply send the user info in the initial payload of the token over having a separate route? Should I be storing a copy in the database in order to do a comparison and retrieve user information?
Also what are the advantages of a token refresh?
you are using Jwt-Auth for authentication.
-According to my knowledge after sending the user credentials u will respond with the token if credentials are correct otherwise send error.
-why are you saving the token in db ?.
you will send token to client (stateless). If client requests for data then we need to check for token. if it validates then return proper response otherwise return token error.
-why you need token refresh?
for security purpose. After response every time change the token.
TTL your token will be valid for some time (say 60 mins). after that it will be invalid.
This is how JWT works.
Related
I'm building a REST API and using AWS Cognito's user pools for authentication. I've got a "get_token" endpoint that returns the JWT access and refresh tokens to the user, which they use to authenticate access to the other REST endpoints provided by the API.
The access token has an expiration timeout. If the user of my API is an application program, what are the best practices for the application to handle when the access token expires? Does the application have to remember the username/password and re-authenticate to continue? Is using the refresh token to get a new access token and use that going forward the best approach?
Is there any documentation, suggestions anyone can point out that might help me out?
Cognito provides 3 types of tokens, id, access and refresh tokens when you login. The way this usually works is that you send either of the first two (depends on whether you want to be sending user payload information to your backend) to your backend via an Authorization header and verify the token there.
Your id and access tokens usually have a shorter expiration time compared to the refresh token. What you should do is, when the id (or access) token expire, you should use the refresh token to generate a new id (or access) token. When the refresh token expires that means that you can no longer generate new id/access tokens from it. In this case, the user (or app) must login again.
I am trying to understand this access_token, refresh_token feature. And this is what I understood:
-- LOGIN:
CREATES access_token;
CREATES refresh_token, sends to DB;
SENDS refresh_token + access_token to client;
access_token expired:
API automatically CREATES a new access_token, using refresh_token;
refresh_token expired: API DENIES all requests, forcing the client to login again.
And i heard that you need to save the refresh_token on a 'sessions' table of database, or smth like it. But i can't understant why, since the client will/may send the refresh_token on all requests. Making it useless to save to DB.
I don't know if i got anything wrong, i hope you can help me out!
What is a little bit awkward (or unclear) in your example - which system creates access and refresh tokens, and sends them to the customers?
Based on the description, I would conclude that this is the identity provider - the client authenticated themselves and got those tokens as a result.
Now when the client calls an API (on a resource provider), they have to include the access token with each request. The resource provider would take the access token and validate it. If the access token is not valid, the API just have to return "access denied".
The client has to use the refresh token to get the new access token from the identity provider and repeat the call to the API on the resource provider.
This would be the typical usage of the flow.
The other common use case is to allow a backend system to do api calls on behalf of the client - in those cases, the backend system has both access token and refresh token; so it can maintain the logged in state even if the client is not around.
It might be that your example is some kind of hybrid solution - both customer and the backend do some calls to IDP.
After doing some research in using JWT with Access Token and Refresh Token for authentication. I understand this in this way.
After login, return to user Access Token and Refresh Token (using same technique JWT for both).
Saving Refresh Token in Database (one User can have multiple Refresh Tokens for multiple devices).
Whenever user sends a request with invalid Access Token, check Refresh Token and call another api to get new Access Token (doing this in client side). After that, call api to get data again with new Access Token.
If Refresh Token is invalid, deleting its record in database and user must to login again to get new Refresh Token.
Does I understand Access and Refresh Token technique correctly? Please give me some advices. Thank in advance.
Of the 4 steps you listed, some look more or less correct while others do not. I will begin this answer by giving the premise for why refresh tokens were created and what is their main purpose.
Using the JWT pattern with only access tokens, there is a potential usability problem when the JWT token expires. Consider as an example a banking website. When a user logs in, he receives a JWT token with a certain expiry (typically stored under the exp key in the claims section of the token). If the token is given say a 5 minute expiry, then from a usability point of view, it means that the website would have to force the user to manually login every 5 minutes. Obviously, this is not the best user experience, because it means that a user who happens to be in the middle of some business process when the token expires might lose all that work. This is where refresh tokens step in to alleviate this problem.
Using the JWT pattern with refresh tokens means that the user receives both an access and a refresh token. A typical workflow here might be:
After login, return to user Access Token and Refresh Token (using same technique JWT for both). The receiver notes when the access token is set to expire (say 15 minutes).
As the expiry of the access token approaches (e.g. 10 minutes), the UI will send the refresh token to the backend to obtain a new access token (and refresh token). This could be done explicitly, e.g. on a website which displays a popup asking if the user wants to continue. Or it could be done in stealth mode, with a REST call being made under the hood to get the new access token.
For the edge case where the refresh token cannot be used to obtain a new access token, then the very next user action which requires authentication would fail. In this case, the user would have to redirected to the login page. But, as this case should generally be rare, it does not disqualify the refresh token pattern.
I would also point out that storing the access/refresh tokens in the database largely defeats the purpose of the JWT pattern. One major reason for using JWT is that it pushes the user session state out of the application and onto the user. By storing tokens in your database, you are totally making your user sessions very stateful, which has all sorts of potential drawbacks. Consider using the suggested workflow above to avoid doing this.
The way I see it, your refresh token needs to be stored and associated with the device and the user.
Example:
User Logs In in Device A
Call Login endpoint
Validate user is valid
If valid, generate a refresh token associated with the userid & device
id
store required data to your table or storage engine (user_sessions..etc)
user_id | device_id | refresh_token | expires_at
Return the payload with access_token, refresh_token , access_token_expires_at, refresh_token_expires_at
Front-end, store the payload
when consuming a resource, check the following
If refresh_token_expires_at > now then logs them out , show your session is timeout (or you can have a never expired refresh_token.. ex. refresh_token_expires_at can be 0)
if access_token_expires_at > now then call refresh token endpoint along with your payload.
on the refresh endpoint, validate the call and check the refresh token against the data stored.
if refresh token is valid for this user+device, generate a new access_token
return the access_token and its expires_at
If the refresh token is INvalid , return invalid
front end will log the user out.
** in any case, if a refresh token was compromised, it will be only for that particular device/user. A user can then deactivate or remove the device from their list. This action will invalidate the refresh_token on their next refresh call.
I want to build a REST API which will be used by both mobile app and also a website. I was wondering how would I go about implementing a simple login system for users?
For a simple website, after checking the username and password, one could set a SESSION variable and have the user "logged in".
Now, REST is stateless so I suspect that the above is not the way to go about. I thought that a possible solution would be to have the server generate and return an access token each time the user logs in, and the client will need to attach this access token to every subsequent request to access protected endpoints.
Is the above a viable solution or what is the industry standard for something like this?
(I found OAuth 2.0 to be overkill, but I could be wrong)
There are several token authentication schemes, but if you're looking for the industry standard, then JWT (JSON Web Token) is the way to go. Here's how the process usually goes:
Client sends his credentials (e.g. username and password) to the server.
The server verifies that the credentials are correct, generates a JWT and returns it to the client. Client saves the token in e.g. localStorage.
For each subsequent request, the client will attach the JWT as a part of the request (usually in the "Authorization" header).
Server will be able to decode the JWT and decide if the client should have access to the requested resource.
Now, some interesting features of JWT come from the fact that there is data encoded in it. Some of it everyone can decode, and some only the server can decode.
So, for example, you could encode the user's id and profile picture in the JWT so that the client can use the data from it, not having to do another request to the server to get his profile.
JWT has embedded info about expiration. The server can set the expiration time.
Another cool thing about JWTs is that they are invalid if changed. Imagine you stole someone's token, but it's expired. You try to change the expire information inside the token to some time in the future, and send it to the server. Server will deem that token invalid, because the contents doesn't match the signature attached, and a valid signature can only be generated by the server.
I am doing an app with a login/logout function and I will be storing the jwt issued by the server in the browser's local storage, for logging out I will destroy it so, if the same user wants to login again it will have to request for a new jwt. However, assuming that i will be using the same credential for the very same user, the same jwt token will be given based on its formula. So, is there a way to issue different jwt per login?