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 the authorize
callback is initialized I pass data received from google 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 in session
, 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 in session
callback? Is the server-side rendering of Next.js
causing the problem?
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)
}
}
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
}
}
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With