Extending the expiration of existing token - authentication

I want to extend my existing token.
I make a facebook authentication with server side call and I got fb access_token with 60 days time.
Then next day I make a call, https://graph.facebook.com/oauth/access_token?client_id=APP_ID&client_secret=APP_SECRET&grant_type=fb_exchange_token&fb_exchange_token=EXISTING_ACCESS_TOKEN
In FB documentation https://developers.facebook.com/roadmap/offline-access-removal/ they says,
our platform will only extend the expiration time once per day, so even if a user revists your site multiple times a day, the token will be extended the first time requested
But I got same access_token without time extended.
How to extend my existing token?
The returned access_token will have a fresh long-lived expiration time, however, the access_token itself may or may not be the same as the previously granted long-lived access_token.”
You told returned token will have fresh long-lived expiration time.
For example EXISTING_ACCESS_TOKEN - valid token with 50 days validity
I make a call with query https://graph.facebook.com/oauth/access_token?client_id=APP_ID&client_secret=APP_SECRET&grant_type=fb_exchange_token&fb_exchange_token=EXISTING_ACCESS_TOKEN.
In that response facebook returned same token and same 50 days time validity. After 50 days this token will be expired.
My question is how to extend my expiration time? Or What is wrong with this query?

But I got same access_token without time extended.
Off course you do, because that's exactly what's descriped under "Scenario 4" here: https://developers.facebook.com/roadmap/offline-access-removal/#extend_token
It's all in there, you just have to read it ;-)
If you pass an access_token that had a long-lived expiration time, the endpoint will simply pass that same access_token back to you without altering or extending the expiration time.
[...]
If you would like to refresh a still valid long-lived access_token, you will have to get a new short-lived user access_token first and then call the same endpoint below.

Related

AWS Cognito - How to keep idToken alive forever?

When the user gets authenticated, AWS Cognito provides three tokens - idToken, accessToken, and refreshToken.
AWS Cognito configurations only allow a maximum of 24 hours expiry time for idToken, see below image.
Now if we look at apps like Facebook, they never expire user login automatically. But in our case, the user needs to log in every 24 hours once.
Question: How can we keep idToken alive forever using refreshToken or something else? Please also guide me in case I need to do it on the server-side, what best I can do to ensure all idTokens are refreshed in a timely manner.
You cannot keep an ID token forever. As you noticed yourself, the maximum validity time for an ID token is 24 hours. There is literally nothing you could do to change this configuration.
There might be a way around it, but you need to keep refreshing the ID token using the refresh token. The refresh token can be configured to expire after 10 years. All you have to do is to keep on using it every time you see that the ID token expired. If you are using an SDK it will normally do it for you. You just sing in once and the SDK will keep on refreshing the ID token.
Just keep in mind that you will get a new ID token (as well as an access token) each time you use the refresh token. It does not update the validity of the original token.

Is it necessary to refresh tokens every request?

I'm here because I wasn't satisfied with what I found on google.
I am generally building SPA's, so for me the process was simple: At succesful login generate a jwt and use it for every request I make from the client.
Someone told me that I should refresh that token and send back a new one for every request I make. Does this make sense for me to do? I mean, if someone is trying to hack me, sniffing the requests will give the hacker the same tokens I receive, so what's the catch?
I mean, what if I launch a request before another one is finished? Teoretically I would send the same token twice and one of the requests will be rejected.
How is this correctly handled? I'm sure there is more to this than what I could think myself.
It is a compromise between security and convenience.
No, you don't need to refresh the token on each request. But you definitely want your JWTs to expire at some point. This is to protect you from JWT theft where malicious user could use stolen access token to gain access to target resource indefinitely.
Here is what you can do to handle token expiration:
Implement a refresh token flow. You will issue an access JWT and a refresh JWT when authenticating. Once access JWT has expired you will use refresh JWT to obtain new access JWT.
Implement sliding expiration. After the half of the JWT validity time has expired you would issue a new JWT. An example of it can be found here. I would recommend to include a deadline to when a token can be expired. For example, initial token validity is for 20 minutes and deadline is 8 hours. After 8 hours of sliding expiration you will stop issuing new tokens.

JWT token refresh (sliding sessions) and signout

I am very new to JWT and I ended up inheriting a codebase which makes use of JWT. Now there are some very fundamental problems which I am facing and I am not finding any answers. This question is not code based so please bear with me.
Let us say that my JWT token is valid for 4 hours. Here are my requirements/constraints
If a user is working at 3 hours 59 minutes. their session should get extended by 2 hours and they should not be required to re-enter credentials.
The client side java script must not cache the user credentials in any way.
It is OK to refresh the JWT token with a new one... but you must not do it on every request you make on the server. So the client has to be intelligent to refresh the JWT token when the time is right. You must not try to issue a new token on each and every request you make to the app, because we will end up in a scenario where we have 1000s of active tokens generated within the course of a session and all of them are active. this makes the signout requirement even harder.
Once a user clicks signout. the JWT token should not be usable anymore. Even though its life time is still valid.
If a signout occurs. All tokens which were issued (as part of session extension) should get invalidated. Not just the last one.
I am starting to read about JWT but it seems like my requirements cannot be met with JWT. these requirements are very easy to meet with the session id approach. but I don't want to give up on JWT just yet.
JWT life extension
You can issue a JWT with the old one. Your client app have to request a new JWT when it is close to expiration time. Client knows the expiration time reading the exp claim and can invoke a refresh service to get a new token. If the client app is closed then the JWT will expire and it will be necessary for the user to present the credentials again
Logout
It is recommended to let tokens expire, but you can use a blacklist to store JWT that are still valid but can not be used for authentication:
When user clicks logout
After refreshing a ticket close to expiration time
You will need to add to JWT an unique identifier jti. The blacklist will contain jti and exp. Once current time > exp the entry can be discarded.
See Invalidating client side JWT session

Alternate approaches to token based authentication

I have a RESTful API which will be users will reach via a set of web/mobile clients, and I am trying to figure out how to handle token auth. My understanding is that traditional token auth works as follows:
User auths by providing user/pass, receives back a token and expiration
Until , token is passed with every request
Upon expiration, a new token is requested (either by providing a separate 'refresh' token or just by re-authenticating with user/pass)
Is there a good reason not to generate a new token with each request? That is: an initial token is requested via user/pass. This token is passed with the first API request, which returns the content of the api response plus a new token which must be passed with the following request... The advantage to this approach would be that each request (action) the user takes 'resets' the expiration of the token auth such that the token expiration time basically becomes the period of time the user can be inactive without being logged out. Is there a good reason not to use this approach? The approach laid out above seems more commonplace (which is why I ask).
Finally, one only slightly related question. What stops someone who is watching the network from grabbing the token from the user? In particular in the first scheme, it seems easy to do (in the second method, you would need to capture the incoming request and then quickly get the next token before the user does).
From what I read is that you want a sliding window in which a user is authenticated. Every new request within the expiry window prolongs the session.
If I understand that correctly I would suggest an alternate approach; every time a request is successfully authenticated update your store in which you have your tokens and update the expiration time.
This way you don't have to bother your users with all the hassle of grabbing the new token every single time.
So, yes, there's a good reason not to do that: it's not necessary for your use case and only annoys the user.
With the above approach I assume that you have a store (database) in which you keep your tokens + an expiration date.
So the process is this:
The user provides username + password
Create record in store
Give user the token
Update store every time a successful request is made
On a related note; don't give the users the expiration date. That's fine when using cookies for example but that is merely useful as an additional security measure.
On your slightly related question; nothing stops anyone from grabbing the token if you don't use TLS/SSL/HTTPS. Always use TLS (which is SSL, which is HTTPS, more or less).

Time expiration issue in JWT

As you know, there are some good reasons for using token based authentication instead of session based.
In session based, of course there is a expiration time. So if user is not active for a while, his session get expired. But before expiring, if he send request to server, his time will be extended.
There is an awesome tutorial here about JWT. I have a question about expiration time for token. Imagine we set the expiration time to 100 seconds, then we sign the token. It doesn't matter user is active or not. After 100 seconds that token will not be valid anymore. This bothers the user. Is there any way to extend the time?
Is it a true approach, or maybe I have a mistake. Any idea?
If I understand the question correctly, it is fairly simple to alter the expiration of a JWT token during creation...
The "exp" (expiration time) claim identifies the expiration time on
or after which the JWT MUST NOT be accepted for processing. The
processing of the "exp" claim requires that the current date/time
MUST be before the expiration date/time listed in the "exp" claim.
More information can be found here https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4
Basically the exp key takes a unix timestamp - set the timestamp to > 100 seconds from now and you will accomplish your goal.
To "refresh" the token your API needs a service that receives a valid, JWT and returns the same signed JWT with the updated expiration.
Silent refresh
There are 2 major problems that users of our JWT based app will still face:
Given our short expiry times on the JWTs, the user will be logged out every 15 minutes. This would be a fairly terrible experience. Ideally, we'd probably want our user to be logged in for a long time.
If a user closes their app and opens it again, they'll need to login again. Their session is not persisted because we're not saving the JWT token on the client anywhere.
To solve this problem, most JWT providers, provide a refresh token. A refresh token has 2 properties:
It can be used to make an API call (say, /refresh_token) to fetch a new JWT token before the previous JWT expires.
It can be safely persisted across sessions on the client!
Here a brilliant exhibition in HASURA BLOG--> https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/
You didn't give further information, but I'll assume you are going to use JWT for web-browser authentication.
you can save your JWT in a cookie with httpOnly and secure attribute and set cookie expiration time long enough(maybe 1 years) and inside of your JWT claims set exp property to a shorter time ( maybe 1 week or something else). now in every request the cookie will be sent to the server so you can check for expiration time.
something like this :
if(decodedJwt.exp < Date.now()){
//token is valid, do your stuff
}else {
//token expired, regenerate it and set it to the cookie
//also update the expire time of the cookie
}