Invalid session for the user, session is expired - amazon-cognito

I created a user on Amazon Cognito using a temporary password. when I logged in using a temporary password I am getting a challenge session token that is having validity less than 5 minutes. is it possible to increase the time? after 5 minutes if is submit the password reset request with that session I am getting Invalid session for the user, session is expired.

No, the whole point of that short time is to boost security. Think of it as an OTP sent to you that you have to verify quickly. Is there any particular reason you want this time extended? 5 minutes is more than enough time to set a new password with the forced password change request.

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.

Sliding Window with expiring JWT Refresh Token

I'm running a website + native apps that communicate via HTTPS with my backend. The following requirements must be fulfilled:
Sliding session on the website. That means if the user interacted with the website within the last xx Minutes, he must not be logged out
Remember me on the website. When this is checked, the user must not be logged out (or after a very long time)
The user must not be logged out on the app
Access can be revoked, either by the user (currently logged in) or specific events (password changes).
What I currently have is the following: A refresh token endpoint generates a JWT when password hash and username match in the database. Every refresh token has a jti that is stored in the database, as well as expiration (for DB cleanup only), device_id and a revoked flag.
Another endpoint can be hit with the refresh token, which returns a JWT access token. The access token is valid for 15 minutes. The access token cannot be revoked.
My problems arise with requirement 1. I do not want the user to reauthenticate when he's interacting with the website. This means I need the refresh token. However, the refresh token must only be valid for e.g. last user interaction + xx Minutes. I cannot extend the access token with every request, as there is no way to blacklist access tokens. This would mean that a leaked access token is like a master key forever (as long as you constantly hit the api in 15-minute intervals). But I also do not know what the expiration for the request token could be.
The second problem is (2) with incognito modes or multiple devices. Assuming the user opens 20 private tabs and uses remember me on all of them. Then I have to store 20 tokens in the database. I could, of course, set a limit for type "web" to say 5 and "app" to 3 and remove the oldest last accessed one from the database (and therefore invalidate it). But this would log him out on the "main" browser if he opens 5 private tabs somewhere. It would also limit the number of phones to e.g. 2.
Different PCs/laptops would also generate many refresh tokens of type web. How would I best identify the corresponding device so access can be revoked, but I also do not store hundreds of refresh tokens over the application's lifetime? Best would be one refresh token per device (windows+firefox, iPhoneA, iPhoneB, windows2+firefox). But identifying desktop PC's is super hard.
What it comes down to is:
How can I store refresh tokens in the DB so they are identifiable to the end-user (e.g. Whatsapp webs "Safari started in New York last used at xxx-xxx-xxx"
How do I avoid having hundreds of tokens per user in the DB (as refresh token basically never expire, and the user can open as many private tabs as he likes without logging off)
How can I implement sliding windows with the refresh/access token pattern? So no unlimited refresh token on the client-side, but also no logoff after the access token expires as long as there is any usage. I could have it in the session storage, but then it still clutters my database and shows to the user as "currently logged in" (which displays all refresh tokens) as it's basically still valid.
Sliding session on the website. That means if the user interacted with the website within the last xx Minutes, he must not be logged out
To solve this problem you can use a refresh token, i.e when the user login for the first time, the application will return a access token (JWT format), with an expiration date set to the amount that you want.
When the user will browse the application, your backend will return a X-Refresh-Token header valid for your xx amount of time (i.e you'll need to return this header for each backend call).
If the acess token is expired (the backend will read the access token used, and perform check on expiration date token field), the backend will return a 401 Unauthorized error,
and your client must call the authentication endpoint, providing the last refresh token stored, to issue a new access token.
With this implementation your requirement #1 is satisfied.
Remember me on the website. When this is checked, the user must not be logged out (or after a very long time)
To solve this one, you'll just need to generate a long lived access token (i.e with an expiration date set to the amount of time you want).
The user must not be logged out on the app
I don't understand this one
Access can be revoked, either by the user (currently logged in) or specific events (password changes).
This one is really tricky. Since backend is stateless, revoking access token is a really complex topic.
Hopefully a lot of pattern existing to solve this one, we just need to discuss about it.

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
}

Update token after password change in Phonegap

I am new to token based authentication and doing the following:
Authenticate the user by email and password,
get a token back from backend,
store the token in local storage,
check to see if a token is present. If yes then user is logged in.
What what I want to achieve is that if the user changes his password then the client should prompt for fresh login. How can this be done?
This depends whether you are using Refresh Tokens or not as user Gopinath Shiva describes in his answer to question about somewhat same domain.
If you use Refresh Tokens, then
When the user changes his password, change the refresh token of the user. Hence the remaining session will get logged out soon.
If you don't, then
When the user changes his password, note the change password time in the user db, so when the change password time is greater than the token creation time, then token is not valid. Hence the remaining session will get logged out soon.

default activerecord store session timeout

Can someone tell me what the default timeout is when using activeRecord store?
I don't want to 'set' the timeout because I want it to behave as a session cookie.
ie: expire when the user closes the browser, which doesn't happen if you manually set the expire date.
When I leave the expire date off, the session will timeout sometime within a couple of hours of no use. Why is this so?
So really what I'm asking is, is it possible for the session to not timeout at all when the user keeps his/her browser open and only expire when he/she hits logout or closes the browser?
Keeping in mind:
the cookie doesn't get deleted if you specify an expiration on the activeRecord session_store when user closes browser.
I think there is two points here, Session Timeout and Page/HTTP Timeout from Web Server.
As far as I understand, ActiveRecord Store Session store doesn't timeout, unless the user moves away from the page.
Alternatively, if the Web Server decides after sufficient time of idle-ness to then drop the connection, which in turn negates the Sessions.