Where and how to change session user object after signing in?
I resolved that problem by myself.
This issue thread helped me a lot!
https://github.com/nextauthjs/next-auth/issues/764
Below is the explanation:
callbacks: {
jwt: async (token, user, account, profile, isNewUser) => {
// "user" parameter is the object received from "authorize"
// "token" is being send below to "session" callback...
// ...so we set "user" param of "token" to object from "authorize"...
// ...and return it...
user && (token.user = user);
return Promise.resolve(token) // ...here
},
session: async (session, user, sessionToken) => {
// "session" is current session object
// below we set "user" param of "session" to value received from "jwt" callback
session.user = user.user;
return Promise.resolve(session)
}
}
EDIT: Due to NextAuth update to v4
Version 4 of NextAuth brings some changes to callbacks shown above. Now there is only one argument assigned to jwt
and session
functions. However, you can destructure it to separate variables. Rest of the code stays the same as before.
https://next-auth.js.org/configuration/callbacks#jwt-callback
https://next-auth.js.org/configuration/callbacks#session-callback
// api/auth/[...nextauth].js
...
callbacks: {
jwt: async ({ token, user }) => {
user && (token.user = user)
return token
},
session: async ({ session, token }) => {
session.user = token.user
return session
}
}
...
Comments
-
MateuszWawrzynski almost 2 years
I have weird problem and I don't know where the problem is. I use next-auth library to make authentication system in my
Next.js
app.Everything is OK - I can sign in by checking if there is account in
google firebase
with submitted credentials,session
is being created properly, but when theauthorize
callback is initialized I pass data received fromgoogle firestore
after correct sign in. User object contains whole data and it's passed forward.Then, when I want to read data from
session
, some data I passed before is missing.Code:
/pages/api/auth/[...nextauth.js]
export default (req, res) => NextAuth(req, res, { providers: [ Providers.Credentials({ name: 'Credentials', credentials: { phone: { label: "Phone number", type: "text" }, password: { label: "Password", type: "password" } }, authorize: async (loginData) => { const { csrfToken, phone, password } = loginData; // checking if there is account with these credentials let res = await login({ phone, password: sha1(md5(password)).toString() }) // 200 = OK if(res.status == 200){ // collect account data const user = { phone, ...res.data.info } // user object is created correctly, whole data is stored there console.log('received account data from firestore', user) return Promise.resolve(user); } else { // wrong credentials return Promise.resolve(null); } } }) ], callbacks: { session: async (session, user) => { console.log('data passed to object when signed in', user) // user object there doesn't have all data passed before return Promise.resolve(session) } }, debug: false })
Console logged objects:
received account data from firestore { phone: '123123123', id: 'w2zh88BZzSv5BJeXZeZX', email: '[email protected]', name: 'Jan', surname: 'Kowalski' }
data passed to object when signed in { name: 'Jan', email: '[email protected]', iat: 1603900133, exp: 1606492133 }
The best thing is, the object (above) always has the same properties. I can pass any object in
authorize
callback, but insession
,user
object always has "name, email, iat, exp" ALWAYS. The only thing that changes are values of these two properties in object (name, email). (rest properties - "phone, id, surname" - are missing).Below there is console logged
session
object in any react component:import { signIn, signOut, useSession } from 'next-auth/client' const [ session, loading ] = useSession(); console.log(session)
Photo of console logged session object
What can I do? Do I have to receive data from
firestore
separately insession
callback? Is the server-side rendering ofNext.js
causing the problem? -
entithat over 3 yearsYou saved my life :)
-
ABCD.ca over 3 yearsThanks, this was a good lead. These days the signature looks more like,
session: async (session, user) => {
. Also, since you're usingasync
you can just returnsession
, you don't need to usePromise.resolve
. -
Richard Vartan Melkonian over 2 yearsthis solved my issue too, thanks for the edit for v4.
-
Chayanin almost 2 yearsThe property to be attached to token and session objects has to be "user" only. I wasted a lot of time trying to name it something else. Finally made it works with this answer. Thanks!