Ошибка при кодировании и декодировании 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",
}),

и не только работает, но и записывает в консоль декодированный токен.

Другие вопросы по тегам