Trying to implement a secure authentication method with JWT for an API which will be consumed for many clients including web (Single Page App), desktop, mobile I've came up with this system:
Client calls /auth/login with username and password set
After verifying server returns two tokens an auth_token and a refresh_token
Auth token is short lived 15 minutes and is used on every following API call
Refresh token is long lived maybe a 12 hrs to a week BUT is signed with a secret key in the format user_pass + long_string
After the token expires a called to /auth/renew is called
The auth token is sent to check how long it's expired (no longer than an hour)
The refresh token is sent as well and is validated using the user's password
If refresh token isn't expired and the auth token isn't expired for a long time, a new auth token is sent back
If the user's password has changed, the refresh token is invalid and the user is required to re-authenticate after their existing short lived auth token has expired
While there is a small window for the auth token to be expired and still be valid, and there is calls to the database made; is this an overall secure way to authenticate using JWT and to handle password changes and token refresh?
Don't try to implement your own authentication infrastructure. Chances you'll get a secure implementation are minimal and now you'll have to maintain all that code also.
Better use a authorization server from a reputable origin, like Thinktecture IdentityServer or Azure Active Directory and use standard libraries and protocols.
Some problems I see with your proposal:
if you do not sign the access token, what prevents me from changing
the claims inside?
if you need the user's password to validate the refresh token, you must store it in a way that you can retrieve it in clear text. Passwords should only be stored as a salted hash preventing you from getting to the clear text.
Related
i'm having a diffculty with Access Token.
And i'm new in web dev, taking a role in front-end.
So far, my web site is connected with server for log in API, and i can verify user infomation after logged in at console.
However, i'm wondering the way to get access to Access Token which is issued from the server.
So, the logic is as follows,
When i sucess logged in with correct user information, AccessToken and Refresh Tokens are issued.
I needed a code to access to Access Token, so if i have, i can access to prevented pages (such as, MyPage)
The Access Token has 30min of expires, so after logged in 30min,the issued Access Token must be expired and lost its access rigth to private pages.
Summary !
I'm wondering the way to code the AccessToken in Client side to server side after logged in. Found some of informations that saying include Access Token in headers request in Client side.
How can i code whether the Access Token is expired after 30 min and reqesting again to issue the access-token when i access to private pages with access-token expired state.
Then, if server can find there is a refresh-token in Client side, then issues access token very easily.
Wondering should i put all of the pages that check wether AccessToken is alive?
Normally, it handle by token middle-ware between front-end to IdP(ID provider) server.
It automatically refresh the access token by refresh-token.
The middle-ware's roles
refresh token together with the access token when the user login is processed.
access token and refresh token are re-issued when the refresh is executed
saved the access token and refresh token into local storage (usually called cookies)
If an access token is expired when you execute an API, it will be able to execute the API with a new access token if a refresh token is valid
If an refresh token is expired when you execute an API, it will be able to execute the API with a new access token if a refresh token is expired after got new refresh token.
Popular IdP is Keycloak provides middle-ware for multiple languages.
Java, Javascript, Python, Spring Boot, Angular, React
sorry, I missed your question
I'm wondering the way to code the AccessToken in Client side to server side after logged in. Found some of informations that saying include Access Token in headers request in Client side.
The front-end access an access token and decode it for getting user's information, role and expires time
How can i code whether the Access Token is expired after 30 min and reqesting again to issue the access-token when i access to private pages with access-token expired state.
middle-ware takes care the life time of access token
Then, if server can find there is a refresh-token in Client side, then issues access token very easily.
Yes,
Wondering should i put all of the pages that check wether AccessToken is alive?
It stored in local storage in single place and use it from mutiple pages
There are a few things I might not agree with in #BenchVue answer:
Client should retrieve user data from ID-tokens only. Access-tokens audience are resource-server(s), can be opaque and should be used only as authorisation headers.
Authorization-server (middle-ware in the answer) defines tokens expiries. It does not refresh it auto-magically. Clients must handle tokens refreshing, which can be done pro-actively as OAuth2 token responses contain expiry in adition to the token itself (even for opaque token).
Do not code a gripped weel. Pick a lib. You're very very likely to make security breaches otherwize. Plus you'll waste a lot of time implementing stuff like:
redirection to authorization-server for login / logout when user tries to access a protected route
silent access-token refreshing (just before it expires) using refresh-token
JWT adding as Bearer Authorization header to secured resource-server
etc.
I have built one authentication using access token, refresh token and refresh token rotation. When a user login, the system generates one JWT token and one UUID hashed refresh token and its refresh token id then return back to user.
The init refresh token is a UUID token and it uses bcrypt to hash the uuid token then saving on the database. On the database, apart from saving the refresh token id and the hashed token, I also saved its expired date, its userId, active status and revoked ip.
The access token is passed inside Authentication header as a Bearer token for JWT verify. When one access token is expired, it calls /refresh-token with the old refresh token value and its id to get a new access token and refresh token pair. If the refresh token is expired, I will ask the user to login again.
I also have a refresh token rotation method to avoid refresh token reusing. When a refresh token reused, I will revoke and disable all the refresh tokens belonging to that userId family. So the user should login again to get the new access token and refresh token pair.
I know OAuth2 is a good protocol to implement access token and refresh token authentication. With my authentication design, how to improve it to make it with OAuth2?
Well it sounds like your UUID has all the powers of a refresh token to a client. And if the client is a browser it should never receive a refresh token - a secure cookie is considered better.
The main things I would recommend are the use an Authorization Server and to follow standard guidance around APIs, web and mobile apps.
OAuth provides a number of security design patterns. It is worth understanding the specifics of web and mobile clients. Also think about security related features such as auditing of tokens issued.
Here are some resources from Curity, where I work. The concepts here apply to any provider - it is the principles that matter:
IAM Primer
Free Authorization Server
Guides
I'm working on a project (nothing production-level, only for leveling up my skills) and I'm using JWT to handle authentication.
From what I've read, using a JWT only as an access token is quite unsafe, and hence we need refresh tokens. So, on login, the server returns an access token and a refresh token (which I will be storing in an httpOnly cookie). The access token expires in a short time, but the refresh token is used to get a new one when it does.
My question is, when do we use the refresh token to get a new access token? Is it when the user wants to get a protected resource and finds that the access token is expired (and the refresh token has not) or do we send a new access token each time the user wants to get the protected resource? I'm confused about when and where the refresh token comes into play.
(I'm using React for the frontend and Nodejs for the server)
You're using some security token so it mean that your system has some protected resources. Those resources can only be accessible on successful validation of the token. As you're using the JWT Token (usually for stateless authentication) and your system is granting both access_token and refresh_token to the client, so on server side you can use some authentication interceptor to validate the access_token in the each private request and return some error code on token expiration. On the client side you could also use some filter which should capture the error code and by utilizing the available refresh_token it should request for new access_token from the server. In case of refresh_token expiration your system should follow the route of fresh authentication.
The refresh token can be used at any time to request a new access token. Checking the validity of the access token before he request is one way of accomplishing that. Another common practice is to refresh the access token if it is within a certain timeframe of the current token expiring. A simple cronjob can work in this case. If you assume the access token is not used in multiple places (which it shouldn't be) then the current access token can be invalidated when the new access token is created. Also, for maximum security, the refresh token should be replaced with the access token. This limits security risk around a long-living refresh token becoming compromised.
Nowadays many developers use the JWT Authentication to authorize the api call.
By the way, if a hacker can capture the api call request of the authenticated user then he can have the authenticated JWT token.
Then the hacker can access this api with the authorized JWT token, without his authenticating.
Is this alright?
I am wondering that the JWT Authentication is actually safe.
Can you explain that?
A jwt is a code that contains information about the identity and claims of a user and is valid for only a limited amount of time.
The code cannot be read nor changed by anyone, except the authorization endpoint that issued the token. It is therefor safe in the sense that it cannot be tampered with. This means that the token can be fully trusted. You don't have to validate the token and you can use the identity information and claims without having to consult the database.
But this is also the disadvantage. Once issued the token is valid until it expires, since the expiration cannot be altered. That is why the token should only be send over a secured line to the server. You wouldn't want a hacker to intercept the token.
But if it happens, then what?
There are several options. You can use short-lived tokens, which means that a token expires short time after being issued. If a token was intercepted, it is only valid for a small amount of time. In that case you take for granted that a hacker can have access for limited time to the system. The advantage is that you need less resources and the effort of hacking is probably not worthwhile.
Another option is to validate the token on each request. This requires more resources (e.g. lookups in the database), though you can use some sort of caching. If something changes, like the ip address, then you can invalidate the token. But the question is if you can detect if a token was send by a hacker.
So it depends on the chosen strategy. But: if you issue a long-lived access token without validation (and thus without the possibility to revoke the token), then you'll have a problem if a hacker gets hold of an access token. So you'll need to do something to use it in a safe way.
While I think this should be enough to help you understand, I would like to mention the use of refresh tokens. If you use short-lived access tokens, then you may want to implement long-lived refresh tokens. These refresh tokens are meant to obtain a new access token after it expires. The advantage is that you don't need to send the credentials, the refesh token suffices. You can however only implement this in an application that can keep a secret. Because you most certainly do not want a hacker to intercept the (long-lived) refresh token.
Being used less frequently (opposed to the access token) you can add logic to validate the refresh token when used. You can consult the database and decide to reject the request (e.g. when ip address changed) and revoke the refresh token. In that case the user has to identify itself again (send credentials).
JWT is just a secure msg transporter between fsb server and client so that fsb server can determine whether the client is logged in or not; if logged in, the fsb server will fetch personal unique user based data.
google oauth
G sends back user gid to my server only if user has a google account and successfully inputs gmail and password correctly.
user id is saved in jwt’s payload.
jwt
if google validates the user and google returns gid
create jwt content and internal maintenance: exp date, encryption
jwt is sent and stored in local store of user’s browser;
each user’s req sends jwt back to my server
my server decodes the jwt using secretOrKey, which only my server has, and gets the content(uid) from the jwt.
if uid is in my db, user had already registered and right now is logged in.
send the requested data from my db to the user because he is logged in
if use fails google validation due to wrong password or G email, jwt isn't created.
Process of JWT
user’s google popup logs in
google server returns information to my server. If the gid isn’t in my db, I’ll save it in my db so that the user can be registered.
create jwt and add uid as content. Exp date.
jwt is sent and stored in local storage of users browser
user requests a page though http, it includes the jwt. my server checks whether this user is logged in or not by Login determination test: if user’s jwt uid is in my DB, user is logged in. the user requested data will be given to the user. If user doesn’t have jwt or uid doesn’t match then the user isn't logged in, send the user to login page.
JWT descriptions
https://medium.com/#rahulgolwalkar/pros-and-cons-in-using-jwt-json-web-tokens-196ac6d41fb4
https://scotch.io/tutorials/the-ins-and-outs-of-token-based-authentication
https://scotch.io/tutorials/the-anatomy-of-a-json-web-token
https://auth0.com/blog/cookies-vs-tokens-definitive-guide/
I'm working on an application that uses a token-based authentication system, where the user provides their username / password and receives a token in return (the token gets saved to the database as well). Then subsequent requests will include this token as a custom header and we can use this to identify the user. This all works fine.
Right now if the user doesn't login for 3 days, we expire the token. I was reading a little about refresh tokens in OAuth and I was wondering if I could somehow implement something similar. i.e. when providing the auth token, I also provide a refresh token which can be used later to request a new auth token. In terms of security though, it seems quite similar to just never expiring the user's auth token in the first place. Should I be sending additional information with the refresh token to validate the user?
In OAuth2, the resource server and authorization server are often not the same.
The refresh token is sent back to the client when the access token is issued and when the token is refreshed. The client needs to authenticate itself (using client id and client secret) to use the refresh token. The resource server never sees the refresh token.
Also, access tokens are not stored at the server side as they have a limited lifetime. Refresh tokens are stored and can therefore be revoked.