Dark Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Custom session expire date #2790

Answered by balazsorban44
aboveyunhai asked this question in Help
Custom session expire date #2790
Sep 18, 2021 * 3 comments * 9 replies
Answered by balazsorban44 Return to top
Discussion options

aboveyunhai
Sep 18, 2021

Question

I want to modify the session expire date to keep it consistency with a one of the token expire date from server.
But I am not sure how the session expire date is handled internally by next-auth.

Currently what I did is just to change the session by

session(session, userOrToken) {
session.expires = userOrToken.refresh_token_expiration;
}
2021-10-18T23:00:01.182Z <---- next-auth default generated string
2021-10-18T18:58:42.618517-04:00 <---- server generated string

You can see there are some format difference between two strings;

My question: Is this enough to be handled automatically by next-auth or there are some extra things I still have to handle.

What I try to achieve is that once server token expires, session will be expired as well, hence user auto logout in this case at the moment of refreshing the page or open the page where session callback is trigged due to session expire.

Of course, I know there are some separated cases I had to handle, I just wonder what happen for this particular one.

How to reproduce

Not applicable

Contributing

No, I am afraid I cannot help regarding this

You must be logged in to vote

The session expiry is not the same as a third party access token. next-auth rotates the session expiry, meaning whenever the client contacts the backend, it will update the session expiry date. (which is basically the cookie lifetime)

with other words, the session doesn't have a fixed/absolute expiry time as usually access tokens have.

If the user doesn't open the page for a while, the cookie will expire and will be removed automatically. so make sure the session expiry is always lower than your access token expiry date, if you cannot refresh the access token.

hope that makes sense!

View full answer

Replies: 3 comments 9 replies

Comment options

balazsorban44
Sep 18, 2021
Maintainer

The session expiry is not the same as a third party access token. next-auth rotates the session expiry, meaning whenever the client contacts the backend, it will update the session expiry date. (which is basically the cookie lifetime)

with other words, the session doesn't have a fixed/absolute expiry time as usually access tokens have.

If the user doesn't open the page for a while, the cookie will expire and will be removed automatically. so make sure the session expiry is always lower than your access token expiry date, if you cannot refresh the access token.

hope that makes sense!

You must be logged in to vote
4 replies
Comment options

aboveyunhai Sep 19, 2021
Author

@balazsorban44 Thanks a lot, that cleans out some of my misunderstanding about the session handling.

Just a follow up, if I don't misunderstand how it works,
To give more context, I indeed have all the token rotation to keep the access token refresh, which all happens inside the jwt callback and the implementation is similar to the doc. https://next-auth.js.org/v3/tutorials/refresh-token-rotation.

So when the next-auth session expire, what happen is that it will re-trig the jwt() callback to re-obtain access_token, possibly via refresh_token (based on the above next-auth doc); But the part that buggy me is that not all backend api will have a new refresh_token. So there is a case when both access and refresh expire.

Since you mention "The session expiry is not the same as a third party access token"
So does it mean I will need to manually logout from the client side via signOut() based on the return session info (it includes the refresh_token_expire_date). There is not such a way to manually set the max-age of the next-auth login status to that refresh_token_expire_date upon the moment of login at the first place.
Hopefully my text wouldn't confused you.

Comment options

balazsorban44 Sep 20, 2021
Maintainer

If the refresh_token expires as well, your user will have to log in again, as there is no way for us (or anyone) to keep them authenticated.

I was recently made aware, that the token rotation tutorial should probably advocate for using a database adapter instead of strong a refresh token in JWT, but at the very least, you should encrypt it!

Comment options

aboveyunhai Sep 20, 2021
Author

@balazsorban44
Yes. I'm fully aware of that. I currently twist part of your token rotation tutorial especially regarding the refresh_token part.
To keep the consistency of token inside session in(next.js server) with remote server, which allows me to connect any remote server Api with JWT/Token support.
I only store the expiration date of both tokens inside the session, use the date to determine expiration and rotation.
The true value of token is encrypted by next-auth JWT and never have chance to be touched by client side.
access_token is only accessible via getToken() in server side, only use it on demand.
Next-auth with the next.js server becomes an auth central middleware/proxy. Also encrypt all the remote Api.
The big pitfall is that there are a lot of heavy work to handle like IP check, ratelimiting, own next/api to cover remote api. Important data consistency between both servers and client.
It allow all the true backend(remote server) API hidden behind the middleware,
which are supported to be done by that remote server as well. It is sort of duplicating the work
May or may not worth it situationally.

Comment options

hjoelh Jan 10, 2026

Answer selected by aboveyunhai
Comment options

aman-godara-ria
Jan 15, 2024

@aboveyunhai how have you implemented the access token rotation logic?
The access token rotation doc that you mentioned has the logic to refresh the access token, but I believe that only works when a user reloads the page or moves to another page.

So I was wondering how you have got it to be happening automatically.

You must be logged in to vote
2 replies
Comment options

aboveyunhai Jan 15, 2024
Author

I can't remember the exact details, There is a jwt and session callback functions you can use to inject remote data, both will be trigged when the client side next jwt has changed, when you open app or change route.
They can also be called periodically via keep-alive in .
Something like, all sudo code, the real implementation is obviously, very complex, because you try to sync two tokens across two servers.

callbacks: {
async jwt(stored_token, ...args) {
// intial
// you need to handle all the init errors and edge cases.
if (login) {
const token_WIth_Remote_Data = await callRemoteBackend();
return token_WIth_Remote_Data
}
// token rotation
// you need to handle all the rotation errors and edge cases.
// if error, maybe logout user or do the attempt several times with a threshold, check network condition?
if (stored_token has "remote token data" or user changing page, reopen page) {
// there is a rotation algorithm you need to implement
// to ensure both remote backend and next.js backend token in sync
const condtion = some_algo_calculation_upon_expired_date(a_global_interval)
if (just expire_token is expired) {
// not need to rotate, just logout user
}
if (algo condition match hence only the rotation token expire) {
// update rotation token. still valid user
const new_token = await refreshTokenFromRemoteBackend();
token = { ...new_token }
}
}
return token.
}
},
async session(session, user_and_token) {
// persist remote token data across session
if (user_and_token){
session.user = user_and_token,user;
session.remote_data = user_and_token.remote_data;
}
return session;
}
}

The above code will be executed in sync if you handle it correctly.

Then in your provider in _app.tsx file or layout.tsx for app router?:

</Provider>
options={{
keepAlive: a_global_interval // this mean the callback will be fired periodically
}}

</Provider>
Comment options

aman-godara Jan 19, 2024

ohh! Thanks a lot. I wasn't expecting such a great answer. I have the whole token rotation working fine, I just wanted to know how others have built their solutions.

Comment options

saurabhg138
Mar 8, 2024

I have a requirement that when closing browser it should expire session. how can we achive it

You must be logged in to vote
3 replies
Comment options

aman-godara Mar 9, 2024

In my opinion, you will have to write a custom logic which runs before tab/browser is closed, you will have to ensure there's enough time for custom logic to run when the tab/browser is closed. I think it is still not a good requirement because what if user's laptop dies out all of a sudden then any custom logic that you might have written won't get time to run.

In that custom logic you will have to forcefully expire users session. For OAuth, you will have to log the user out by making a signout API call to identity provider.

Comment options

aboveyunhai Mar 9, 2024
Author

Just use session storage. All data will be discarded upon the app close. You shall not rely on any custom logic to detect user behavior like tabs, leaving windows, etc.

Comment options

saurabhg138 Mar 11, 2024

@aboveyunhai Can you guide me through it? currently my token stored as cookie with lifetime of 1 day (JWT expiration)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Help
Labels
question Ask how to do something or how something works
6 participants
Converted from issue

This discussion was converted from issue #2789 on September 18, 2021 23:42.