Ошибка при кодировании и декодировании jwt на следующей авторизации
При следующей аутентификации, когда просто используется объект обратных вызовов https://next-auth.js.org/configuration/callbacks , все работает нормально, я могу войти в систему с помощью Google. и jwt генерируется правильно.
callbacks: {
async jwt({ token }) {
console.log("token callback jwt: ", token)
token.userRole = "admin"
return token
},
async session(session) {
console.log("session callback: ", session)
const encodedToken = await jwt.sign(session.session.user, jwtSecret.key, {
algorithm: jwtSecret.type,
})
session.token = encodedToken
return session
},
},
Но моя конечная цель — использовать jwt next-auth с hasura, и для этого мне нужно закодировать дополнительную информацию в мой jwt.
Я кодирую эту информацию внутри объекта jwt https://next-auth.js.org/configuration/options#jwt
это мой объект jwt с логикой кодирования и декодирования
jwt: {
encode: async ({ token }) => {
const tokenContents = {
id: token.id,
name: token.name,
email: token.email,
picture: token.picture,
"https://hasura.io/jwt/claims": {
"x-hasura-allowed-roles": ["admin", "user"],
"x-hasura-default-role": "user",
"x-hasura-role": "user",
"x-hasura-user-id": token.id,
},
iat: Date.now() / 1000,
exp: Math.floor(Date.now() / 1000) + 24 * 60 * 60,
sub: token.id,
}
const encodedToken = jwt.sign(tokenContents, jwtSecret.key, {
algorithm: jwtSecret.type,
})
return encodedToken
},
decode: async ({ token }) => {
const decodedToken = jwt.verify(token, jwtSecret.key, {
algorithms: jwtSecret.type,
})
console.log("decodedToken: ", decodedToken)
return decodedToken
},
},
когда я пытаюсь войти в систему с моей новой логикой декодирования кодирования, я получаю следующую ошибку, которая исходит от node_modules> openid-client> lib> client.js
https://next-auth.js.org/errors#oauth_callback_error checks.state argument is missing {
error: {
message: 'checks.state argument is missing',
stack: 'TypeError: checks.state argument is missing\n' +
' at Client.callback (/var/task/node_modules/openid-client/lib/client.js:385:13)\n' +
' at oAuthCallback (/var/task/node_modules/next-auth/core/lib/oauth/callback.js:112:29)\n' +
' at processTicksAndRejections (internal/process/task_queues.js:95:5)\n' +
' at async Object.callback (/var/task/node_modules/next-auth/core/routes/callback.js:50:11)\n' +
' at async NextAuthHandler (/var/task/node_modules/next-auth/core/index.js:139:28)\n' +
' at async NextAuthNextHandler (/var/task/node_modules/next-auth/next/index.js:21:19)\n' +
' at async /var/task/node_modules/next-auth/next/index.js:57:32\n' +
' at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils/node.js:182:9)\n' +
' at async NextNodeServer.runApi (/var/task/node_modules/next/dist/server/next-server.js:386:9)\n' +
' at async Object.fn (/var/task/node_modules/next/dist/server/base-server.js:488:37)',
name: 'TypeError'
},
providerId: 'google',
message: 'checks.state argument is missing'
}
Просто из любопытства я зашел в файл client.js, где код ломается, и это код внутри, у него есть if !checks.state throw new TypeError
if (params.state && !checks.state) {
throw new TypeError('checks.state argument is missing');
}
Кажется почти очевидным, что мне нужно добавить этот checks.state в мою логику кодирования, но я не знаю, как это сделать, и я не знаю, что этот объект checks.state представляет
1 ответ
Хорошо, пока я писал это, я нашел кусок кода, который решил проблему. на странице задач из next-auth https://github.com/nextauthjs/next-auth/issues/3251
кто-то говорит, что если добавить
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
checks: console.log(),
}),
к вашей конфигурации GoogleProvider это работает, и это сработало! Почему? Я до сих пор не знаю, но все же делюсь, потому что это может сэкономить дни исследований кому-то другому.
обновление, из ссылки на проблемы, которой я поделился, я также пробовал
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
checks: "both",
}),
и не только работает, но и записывает в консоль декодированный токен.