I have integrated discord SSO to sign users in as well as create them an account if one has not been created. Now, I am stuck between deciding if I should use sessions or JWT with local storage on the client to prevent the user having to sign in until expiration. I’m struggling to find any documentation or resources for best practices on how long sessions or JWTs can be persisted for before requiring a user to resign in with SSO. Does anyone have resources or tips on expiration lifetimes for users using SSO?
Ideally, I would want to do something similar to how stackoverlow persists SSOs before requiring a user to sign in again. I’m assuming the life times of a session or refresh token will be the same before requiring the user to re sign in. I would prefer to use JWT since my authorization is based of the users guild roles, which allows me to revoke a token if a user had a role removed and other types of scenarios that I would want to issue the user a new access token.
I have tried asking around in a few discords as well as googling best for how long SSO sessions or JWTs should last until expiring and requiring the user to login again. Unfortunately, I have not found a good source for best or common practices for SSO expiration times.
I am having some trouble grasping the role of the refresh token flow within modern SAML/OAuth/OIDC methods.
I understand that authentication is about proving a user is who they say they are, while authorization is about proving a user has access to any particular resource. I also understand that refresh tokens can be used to to handle both.
My question is, how does the refresh/access token flow fit within authentication/authorization methods like OAuth2.0 and OIDC? Is it a subset of these auth methods, or just an optional technique sometimes employed by them? Or are they unrelated to and are like comparing pineapples to oranges?
When it comes to building authentication into a system using the refresh token flow, it is not considered OAuth or OIDC unless if it is built to specifications defined here, correct?
edit: To be more succinct - OAuth seems like a "complete" authentication method. Is the refresh token flow also considered a "complete" solution alongside OAuth, or is it just a technique that is used within OAuth?
When the user has authenticated and got the access token, it will expire after a pre-configured time (e.g. 10 minutes). But to keep the user signed in longer than the expiration time, a refresh token can be used to request a new access token (e.g. valid for additional 10 minutes), and you typically also get a new refresh token.
In other words, the refresh token is a way to keep the "user session" alive for longer than the expiration time of an access token.
A refresh token typically have different security properties, e.g. it can typically only be used one time.
I tried auth0 and I face a problem where I can't block or force logout a user.
After i blocked a user from auth0 console, The user who was logged in could still access the routes.
I used express-openid-connect middleware and requiresAuth()
I suppose this is a common problem with JWT based service ? and should I implement a statefull session to manage user for these kind of use cases ?
In JWT based services it’s common practice to make the access token lifetime a short one, e.g. 10-15 minutes. That way user can still access the api inside a short window but soon the token needs to be refreshed. And when token refresh takes place the authentication service gets called and can reject granting a new token.
So you can make sure your access token lifetime is short enough and that should be enough to satisfy the security requirements.
It’s of course technically possible that you implement stateful session to check user info on each request but you should not call Auth0 api in this case cause you are going to hit their rate limiter and it slows down your api requests. Some sort of sync to your server side fast read database/cache would be needed.
Normally Google Access token is valid for one hour but I want to set it to no expiry. How can I do that, please help
Google access tokens are only good for one hour this is Oauth2 standard and can not be changed. You will need to use a refresh token to request a new access token. No idea if that is possible with dialogflow you will likely have to request your user authenticate again after an hour.
OT: Thats an impressive app you are working on if your users will be using it beyond the access token limit.
According to [1], OAuth token maximum lifetime is 1 hour (3600 seconds) and it cannot be changed.
If your intention is that your application may continue working without having to "manually" recreate a new token, then you could try creating a session client that scopes to multiple requests, as described in the Best Practices Dialogflow reference [2]:
"To improve performance, you can use a single instance of a session client object for multiple requests. The session client reuses the same access token for as long as it is valid (typically one hour). Once it expires, the session client refreshes the access token automatically, so you don't need to recreate the session client to refresh your access token. Your request that also refreshes the access token can take an extra second or two".
Please, try this and let me know the results.
[1] https://cloud.google.com/iam/docs/creating-short-lived-service-account-credentials#sa-credentials-oauth
[2] https://cloud.google.com/dialogflow-enterprise/docs/best-practices
i have to confess i've had this question for a very long time, never really understand.
say auth token is like a key to a safe, when it expires it's not usable anymore. now we're given a magic refresh token, which can be used to get another usable key, and another... until the magic key expires. so why not just set the expiration of the auth token as the same as refresh token? why bother at all?
what's the valid reason for it, maybe a historical one? really want to know. thanks
I was reading an article the other day by Taiseer Joudeh and I find it very useful he said:
In my own opinion there are three main benefits to use refresh tokens which they are:
Updating access token content: as you know the access tokens are self contained tokens, they contain all the claims (Information) about the authenticated user once they are generated, now if we issue a long lived token (1 month for example) for a user named “Alex” and enrolled him in role “Users” then this information get contained on the token which the Authorization server generated. If you decided later on (2 days after he obtained the token) to add him to the “Admin” role then there is no way to update this information contained in the token generated, you need to ask him to re-authenticate him self again so the Authorization server add this information to this newly generated access token, and this not feasible on most of the cases. You might not be able to reach users who obtained long lived access tokens. So to overcome this issue we need to issue short lived access tokens (30 minutes for example) and use the refresh token to obtain new access token, once you obtain the new access token, the Authorization Server will be able to add new claim for user “Alex” which assigns him to “Admin” role once the new access token being generated
Revoking access from authenticated users: Once the user obtains long lived access token he’ll be able to access the server resources as long as his access token is not expired, there is no standard way to revoke access tokens unless the Authorization Server implements custom logic which forces you to store generated access token in database and do database checks with each request. But with refresh tokens, a system admin can revoke access by simply deleting the refresh token identifier from the database so once the system requests new access token using the deleted refresh token, the Authorization Server will reject this request because the refresh token is no longer available (we’ll come into this with more details).
No need to store or ask for username and password: Using refresh tokens allows you to ask the user for his username and password only one time once he authenticates for the first time, then Authorization Server can issue very long lived refresh token (1 year for example) and the user will stay logged in all this period unless system admin tries to revoke the refresh token. You can think of this as a way to do offline access to server resources, this can be useful if you are building an API which will be consumed by front end application where it is not feasible to keep asking for username/password frequently.
I would like to add to this another perspective.
Stateless authentication without hitting the DB on each request
Let's suppose you want to create a stateless (no session) security mechanism that can do authentication of millions of users, without having to make a database call to do the authentication. With all the traffic your app is getting, saving a DB call on each request is worth a lot! And it needs to be stateless so it can be easily clustered and scaled up to hundreds or even thousands of servers.
With old-fashioned sessions, the user logs in, at which point we read their user info from the database. To avoid having to read it again and again we store it in a session (usually in memory or some clustered cache). We send the session ID to the client in a cookie, which is attached to all subsequent requests. On subsequent requests, we use the session ID to lookup the session, that in turn contains the user info.
Put the user info directly in the access token
But we don't want sessions. So instead of storing the user info in the session, let's just put it in an access token. We sign the token so no one can tamper with it and presto. We can authenticate requests without a session and without having to look up the user info from the DB for each request.
No session ... no way to ban users?
But not having a session has a big downside. What if this user is banned for example? In the old scenario we just remove his session. He then has to log in again, which he won't be able to do. Ban completed. But in the new scenario there is no session. So how can we ban him? We would have to ask him (very politely) to remove his access token. Check each incoming request against a ban list? Yes, would work, but now we again have to make that DB call we don't want.
Compromise with short-lived tokens
If we think it's acceptable that a user might still be able to use his account for, say, 10 minutes after being banned, we can create a situation that is a compromise between checking the DB every request and only on login. And that's where refresh tokens come in. They allow us to use a stateless mechanism with short-lived access tokens. We can't revoke these tokens as no database check is done for them. We only check their expiry date against the current time. But once they expire, the user will need to provide the refresh token to get a new access token. At this point we do check the DB and see that the user has been banned. So we deny the request for an access token and the ban takes effect.
The referenced answer (via #Anders) is helpful, It states:
In case of compromise, the time window it's valid for is limited, but
the tokens are used over SSL, so unlikely to be compromised.
I think the important part is that access tokens will often get logged (especially when used as a query parameter, which is helpful for JSONP), so it's best for them to be short-lived.
There are a few additional reasons, with large-scale implementations of OAuth 2.0 by service providers:
API servers can securely validate access tokens without DB lookups or RPC calls if it's okay to not worry about revocation. This can have strong performance benefits and lessen complexity for the API servers. Best if you're okay with a token revocation taking 30m-60m (or whatever the length of the access token is). Of course, the API servers could also keep an in-memory list of tokens revoked in the last hour too.
Since tokens can have multiple scopes with access to multiple different API services, having short-lived access tokens prevents a developer of API service for getting a lifelong access to a user's data on API service B. Compartmentalization is good for security.
Shortes possible answer:
Refresh tokens allow for scoped / different decay times of tokens. Actual resource tokens are short lived, while the refresh token can remain valid for years (mobile apps). This comes with better security (resource tokens don't have to be protected) and performance (only the refresh token API has to check validity against DB).
The following is an addition to the benefits of refresh tokens that are already mentioned.
Safety First!
Access tokens are short-lived. If someone steals an access token, he will have access to resources only until access token expires.
"...But what if a refresh token is stolen?"
If an attacker steals the refresh token, he can obtain an access token. For this reason, it it recommended that a new refresh token is issued each time a new access token is obtained. If the same refresh token is used twice, it probably means that the refresh token has been stolen.
When the refresh token changes after each use, if the authorization
server ever detects a refresh token was used twice, it means it has
likely been copied and is being used by an attacker, and the
authorization server can revoke all access tokens and refresh tokens
associated with it immediately.
https://www.oauth.com/oauth2-servers/making-authenticated-requests/refreshing-an-access-token/
Of course, this is just another layer of security. The attacker can still have time to obtain access tokens, until the refresh token is used a second time (either by the attacker or the real user).
Always keep in mind that the refresh token must be stored as securely as possible.