-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add tutorial on user-land refresh token usage #1079
Comments
I'm happy to help with this one! |
@lawrencecchen Please do, just open a PR, so we can follow your progress! 🙂 |
I've created a sample using Google's OAuth 2 here. However, I'm confused about the client's session response when using the {
"user": {
"provider": "google",
"type": "oauth",
"id": "114609347520974957949",
"refreshToken": "1//0634DctwasdfklDSAYIARAAGAYSNwF-L9Ir2ZtBT1MZlQ935LZrKfaskljwlr4ilJw31fFqyMdlJVO2s",
"accessToken": "ya29.a0AfH6SMAkfYzR9E-9-TTOMpcB0Mmwk57NZGpsd6LwAr3oCll1-ydTFxkbEBSRFNwa02IHlaWXjyNpDtwVCojYDLyy4ApJ9vK2lh12fM4i2IQe6L2ulKxis8wMELc-HWCTlnYmjnjsDTiVghwI8ImlLzzxfChOtmViVtE6c-MVguw",
"accessTokenExpires": null
},
"iat": 1610496123,
"exp": 1613088123,
"accessToken": "ya29.a0AfH6SMAkfYzR9E-9-TTOMpcB0Mmwk57NZGpsd6LwAr3oCll1-ydTFxkbEBSRFNwa02IHlaWXjyNpDtwVCojYDLyy4ApJ9vK2lh12fM4i2IQe6L2ulKxis8wMELc-HWCTlnYmjnjsDTiVghwI8ImlLzzxfChOtmViVtE6c-MVguw",
"accessTokenExpires": 1610498482446
} Why does user.accessTokenExpires default to null? Is my example implemented correctly? I'll PR the tutorial post in the next few days after I figure this out. Lastly, I'm not sure if I create a live demo using Google because of their limits imposed on unverified apps. Any workarounds for this? |
@lawrencecchen you can now access You can learn more about why |
I was trying to do this for Azure AD authentication but problem with this is that the cookie is getting too big when adding both access and refresh token to the jwt token.. No option to set refresh_token in another cookie, so should at least be mentioned as a limitation when not using any database backend. |
@tesharp yes, that is an unfortunate browser limitation. I did mention it in my PR #951 (comment), and had an idea splitting things up, but if I remember our chat with @iaincollins, he had some reasoning why we should not split it up. UPDATE: We will have another internal discussion about how we could support token rotation for non-db users. I don't have a date yet, unfortunately. UPDATE: I added a user-land implementation for token rotation for non-db users at the original description. |
@balazsorban44 thank you for the token refresh boilerplate code! A few small corrections though: accessTokenExpires: Date.now() + refreshToken.expires_in * 1000, should be accessTokenExpires: Date.now() + tokens.expires_in * 1000, Also it's unnecessary to pass the |
Thank you for your concerns! Let me explain: I guess it's provider specific then (which would be sad, bigger chance for edge cases when we will implement this internally 😒), because I wrote that one specifially for our IdentityServer 4 usecase: The spec says:
Auth0 sends it as well: https://auth0.com/docs/tokens/refresh-tokens/use-refresh-tokens So at the end, I at least dont think sending it is any harm. I should probably check more providers, but I have a hunch that most of them will work with thre secret, where some of them wouldn't. So I think it's just safer to send it anyway. Also, |
Possibly, for me personally it's not required on a default public client and standard authorization code flow in Keycloak. The spec needs to be a bit flexible in its definition of client authentication since there are so many possible permutations and applications of the various flows. I guess it really comes down to developer preference for interacting with a particular OAuth2 IdP. IMHO: if a user retrieves an access token by logging in via authorization code flow on a public endpoint, then it makes little sense to force them to present a client secret in addition to the refresh token; the refresh token in that context already authenticates the user. Requiring a client secret would also require more information than a client would have needed to provide if the auth code flow was used to retrieve the access and refresh token in the first place. (This would break token refresh for any purely in-browser application that authenticates this way) Note on Auth0's refresh documentation:
In my case with a standard Keycloak setup it does not: I can't access the refreshToken in that context, here the various outputs:
Expired token{ accessToken: 'XXXXX', accessTokenExpires: 1612767367916, refreshToken: 'XXXXX', user: { sub: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', email_verified: true, 'my_client_id': { user_id: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' }, name: 'Bobby Tables', preferred_username: 'btables', locale: 'en', given_name: 'Bobby', family_name: 'Tables', email: 'bobby@example.com' }, iat: 1612767634, exp: 1615359634, error: undefined } Newly refreshed token{ access_token: 'XXXXX', expires_in: 300, refresh_expires_in: 0, refresh_token: 'XXXXX', token_type: 'Bearer', id_token: 'XXXXX', 'not-before-policy': 0, session_state: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', scope: 'openid offline_access profile email' } My only option here is to use the current timestamp plus the token validity period 😕 |
If you have implementation issues, please open a question in https://github.com/nextauthjs/next-auth/discussions or if you think there is a bug in |
🎉 This issue has been resolved in version 3.5.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
🎉 This issue has been resolved in version 4.1.0-next.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
🎉 This issue has been resolved in version 4.0.0-next.5 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This doesn't work and the docs haven't been changed yet regarding this. |
Summary of proposed feature
There is some confusion about how refreshing tokens can happen or what expiration means in the context of
next-auth
and a given provider. This probably stems from that users simply expect the access token to be always up-to-date when used. We don't currently support automatic access token refreshing, but it CAN be implemented by the users. Until we have built-in support, it would be nice to add a tutorial on how to do it by the user.Purpose of proposed feature
It could either be a standalone tutorial page in https://next-auth.js.org/tutorials or could be an external link to a post, preferably with code example, maybe even an accessible live demo and source code.
Describe any alternatives you've considered
Preferably this should already be a built-in feature, but until we do have this, a tutorial would be useful to link confused users to.
Additional context
Here is my approach using IdentityServer 4, but probably any OIDC compliant provider would do. The code assumes at least
next-auth@3.2.0
:Up for grab, as a good first issue.
The text was updated successfully, but these errors were encountered: