-
-
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
Is there a sane way to store tokens created by a service? #325
Comments
Hey thanks for the detail and for feedback on documentation. I think I understand what you want to do and it makes sense. I actually had to check to see what would happen when I tried it because it's a reasonable expectation but I wasn't sure it was supported or not.
^ Doh was wrong, the problem was with the example code in the Documentation not in NextAuth.js itself! It actually works and there is no bug. |
@iaincollins Thanks, but the problem isn't that I can't get at the export default function handleRequest(req, res) {
return nextAuth(req, res, makeConfig(req, res))
}
function makeConfig(req, res) {
const authorize = makeAuthorizeFn(req, res)
// redacted
}
export function makeAuthorizeFn(res) {
return async function authorize({ username, password }) {
const client = makeClient()
try {
const {
data: {
access,
refresh,
},
} = await client.post('/auth/tokens', {
email: username,
password,
})
// This is a bit hacky, but at least it gets the tokens back
// to the client.
res.setHeader('Set-Cookie', [
serialize('access', access, { path: '/' }),
serialize('refresh', refresh, { path: '/' }),
])
// redacted
} |
Oh sure! The idea is that you should be able to set them on the user object and for that to get persisted (securely) in the JWT. |
One thing to note here is that when I tried to set anything other than `{id, name, email, image }` to the `user` object, it would not make it into the session. I didn't dig far enough in the code to figure out why or where the other keys were be weeded out.
|
If you add a property to the user object in this scenario, then it's persisted to the JSON Web Token (assuming you use the work around above until the bug is fixed - when it's fixed you won't need to touch the The |
@iaincollins, while I did notice that the example provided in the documentation was setting the user as a function, I do not have that problem because I'm already resolving the Here's the entirety of my export function makeAuthorizeFn(res) {
return async function authorize({ username, password }) {
const client = makeClient()
try {
const {
data: {
access,
refresh,
},
} = await client.post('/auth/tokens', {
email: username,
password,
})
// This is a bit hacky, but at least it gets the tokens back
// to the client.
res.setHeader('Set-Cookie', [
serialize('access', access, { path: '/' }),
serialize('refresh', refresh, { path: '/' }),
])
const { data: user } = await client.get('/users/me', {
headers: {
Authorization: makeAuthHeader(access),
}
})
// N.B.: Adding fields to the user object at this point does not work
return user
} catch (error) {
console.error('ERROR: %o', error)
return null
}
}
} Just for grins and giggles, I tried adding {"user":{"name":"Dan Kreft","email":"blarg@foo.com","image":null},"expires":"2020-07-24T23:20:32.599Z"} This is what I was referring to in my previous comment. I cannot simply use the |
Updated example below! This is what your callbacks need to look like: callbacks: {
session: async (session, token) => {
// Copy properties from token contents to the client side session
//
// By default only 'safe' values like name, email and image which are
// typically needed for presentation purposes (e.g. "you are logged in as…")
// to avoid exposing sensitive information to the client inadvertently.
session.user.data = token.user.data
return Promise.resolve(session)
}
}
The stuff I wrote about the user response being wrong was totally incorrect! This amend example above works :-) The example in the documentation I wrote for the Credentials plugin just a has a bug in it 🤦♂️ |
Note that |
Okay, now I see what's going on here. It's a little confusing the way it's laid out here because I never would have thought that the At this point, though, I'm thinking that I'm probably going to stick with my current Thanks for your diligence...I feel more confident in using NextAuth knowing that you're so attentive. :-) |
The purpose of it whenever I give an example code is to make it clear the function is async and a promise is expected. (Otherwise people then immediately ask "How can I do async calls?")
To clarify, as per the docs it's always the contents of the JSON Web Token as the second argument to the For users who are using other configurations, other data will be stored in the JWT (e.g. a user object from a database and/or the profile response from an OAuth Provider). The
Any properties accessed via a session object are be automatically kept up to date, and kept in sync across tabs and windows, and are persisted across page navigation in a single page app so that people can avoid doing exactly this (which actually, you have done - you have put tem. I'd recommend to anyone else reading this they use the session property, if nothing else it's much less code to maintain and makes it easier to avoid bugs. To confirm for anyone reading this in future, this is all you need to do to add data to a session from if you return it in a user object from callbacks: {
session: (session, token) => {
session.user.data = token.user.data
return session
}
} If you do that, they will be there when you access the |
@iaincollins I'm taking another look at using the session (I was ignorant of |
Is it possible to use store provided by an existing non-OAuth authentication service?
I'm trying to use
Providers.Credentials
to integrate with an existing backend services that issues JWTs, but I'm having a heck of a time figuring out how to make this work.When I
POST /auth/tokens
with the credentials, the access and refresh tokens are handed back to me. I need to have these tokens available to me in the API layer so that I can add them to the request headers of subsequent requests, but it's not clear to me how to sanely store these for later access (storing them in a global or singleton in a package feels side-effecty and generally "icky").Here's what I have so far:
Documentation feedback
I've even dug through the source code a little to see if there was a way to "sneak" these tokens into the session, but I didn't see a clear path forward.
The text was updated successfully, but these errors were encountered: