Using next.js auth (next auth) I'm creating CredentialsProvider, trying to connect it to django backend. All is working good except refresh token strategy: after obtaining new access token, access token and expire date not saving. So next auth is sending refresh token every request. I don't know why, but I can't update token data after "first time token created".
Here is the code:
async function refreshAccessToken(token) {
console.log('UPDATE')
const refresh = await axios
.post('/token/refresh/', {
refresh: token.refreshToken
})
.catch((error) => {
console.log(error)
})
if (refresh && refresh.status === 200 && refresh.data.access) {
return {
...token,
accessToken: refresh.data.access,
expiresAt: Date.now() + 10 * 1000
}
}
return {
...token,
error: 'RefreshAccessTokenError'
}
}
export default NextAuth({
providers: [
CredentialsProvider({
id: 'credentials',
name: 'my-project',
async authorize(credentials) {
const auth = await axios
.post('/token/', {
username: credentials.username,
password: credentials.password
})
.catch((error) => {
console.log(error)
})
if (auth.status === 200 && auth.data.access) {
const profile = await axios
.get('/v1/profile/', {
headers: {
Authorization: `Bearer ${auth.data.access}`
}
})
.catch((error) => {
console.log(error)
})
if (profile.status === 200 && profile.data) {
return {
...profile.data,
tokens: auth.data
}
}
}
return null
}
})
],
pages: {
signIn: '/login'
},
callbacks: {
jwt: async ({ token, user, account }) => {
if (account && user) {
return {
// works normally
accessToken: user.tokens.access,
refreshToken: user.tokens.refresh,
expiresAt: Date.now() + 10 * 1000,
user
}
}
if (Date.now() < token.expiresAt) {
return token
}
// token is obtaining in refreshAccessToken but not saved...
// next request refreshAccessToken will be called again...
return refreshAccessToken(token)
},
session: async ({ session, token }) => {
session.user = token.user
session.token = token.accessToken
return session
}
},
debug: true
})
Any help please. Here is simplified example:
jwt: async ({ token, user, account }) => {
console.log(token.expiresAt)
// here token.expiresAt will NEVER be equals 'hey'
if (account && user) {
return {
accessToken: user.tokens.access,
refreshToken: user.tokens.refresh,
expiresAt: Date.now() + 10 * 1000,
user
}
}
if (Date.now() < token.expiresAt) {
return token
}
token.expiresAt = 'hey'
return token
}