You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextAuth v4自定义Sketchfab OAuth提供者时遇state缺失RPError

NextAuth v4 自定义Sketchfab隐式授权OAuth2流程出现state缺失错误

环境信息

  • Next.js 13.2.4
  • NextAuth 4.21.1
  • 部署平台:Vercel
  • 页面配置:仅域名根目录有包含signin()按钮的登录页

自定义Provider配置代码

import NextAuth, { NextAuthOptions } from "next-auth"

const SKETCHFAB_CLIENT_ID = "REDACTED"
const SKETCHFAB_AUTHORIZE_URL = "https://sketchfab.com/oauth2/authorize/"

export const authOptions: NextAuthOptions = {
  providers: [
    {
      id: "sketchfab",
      name: "Sketchfab",
      type: "oauth",
      authorization: {
        url: SKETCHFAB_AUTHORIZE_URL,
        params: {
          scope: "read",
          response_type: "token",
        },
      },
      checks: ["state"],
      clientId: SKETCHFAB_CLIENT_ID,
      profile(profile, tokens) {
        return {
          id: profile.sub,
          name: profile.name,
          email: profile.email,
        }
      },
    },
  ],
  session: {
    strategy: "jwt",
  },
  jwt: {
    secret: process.env.NEXTAUTH_SECRET,
  },
  debug: true,
}

export default NextAuth(authOptions)

错误详情

从Sketchfab授权完成跳转回应用时,抛出state missing from the response错误,Vercel服务器错误日志如下:

[next-auth][error][OAUTH_CALLBACK_ERROR] 
https://next-auth.js.org/errors#oauth_callback_error state missing from the response {
  error: RPError: state missing from the response
      at Client.oauthCallback (/var/task/node_modules/openid-client/lib/client.js:524:13)
      at oAuthCallback (/var/task/node_modules/next-auth/core/lib/oauth/callback.js:111:29)
      at async Object.callback (/var/task/node_modules/next-auth/core/routes/callback.js:52:11)
      at async AuthHandler (/var/task/node_modules/next-auth/core/index.js:201:28)
      at async NextAuthHandler (/var/task/node_modules/next-auth/next/index.js:24:19)
      at async /var/task/node_modules/next-auth/next/index.js:60:32
      at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils/node.js:372:9)
      at async NextNodeServer.runApi (/var/task/node_modules/next/dist/server/next-server.js:514:9)
      at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:828:35)
      at async Router.execute (/var/task/node_modules/next/dist/server/router.js:243:32) {
    name: 'OAuthCallbackError',
    code: undefined
  },
  providerId: 'sketchfab',
  message: 'state missing from the response'
}

登录页面Debug日志

[next-auth][debug][CREATE_STATE] { value: 'Jt_U13aNxYIBiyd-uEQ9P5ECjlPzClMQkACAk-o4WYE', maxAge: 900 }
[next-auth][debug][GET_AUTHORIZATION_URL] {
  url: 'https://sketchfab.com/oauth2/authorize/?client_id=REDACTED&scope=read&response_type=token&redirect_uri=https%3A%2F%2Fproduct-kraken.skyixd.com%2Fapi%2Fauth%2Fcallback%2Fsketchfab&state=Jt_U13aNxYIBiyd-uEQ9P5ECjlPzClMQkACAk-o4WYE',
  cookies: [
    {
      name: '__Secure-next-auth.state',
      value: 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..Nj7ht69QuSSUvEvd.rqMbFxOxA99sHnfrGRpn7dkoC91UYe_jFfZcMqqZE4y7wVg-xfpUp5277jp7uzSdGM4YLvD1IrTDk5hyC_1yzF4cNiM-ooMjeeZt4L5L4yaND2mt2aK7oN60Y4AzcPPcAH_axVEuEer29rbTBieBNJIccvWHgPe9tZLTfmOdVhlvMi2p1J4.RorKlTuYxNLsiqxglAzgqg',
      options: [Object]
    }
  ],
  provider: {
    id: 'sketchfab',
    name: 'Sketchfab',
    type: 'oauth',
    authorization: {
      url: 'https://sketchfab.com/oauth2/authorize/',
      params: [Object]
    },
    checks: [ 'state' ],
    clientId: 'REDACTED',
    profile: [Function: profile],
    idToken: false,
    signinUrl: 'REDACTED/api/auth/signin/sketchfab',
    callbackUrl: 'REDACTED/api/auth/callback/sketchfab'
  }
}

关键观察

跳转回应用的URL中确实包含state参数,但参数位于URL的hash部分:

/api/auth/signin?error=OAuthCallback#access_token=qi7L2kbPCcm68sYsvZ8ZAIiG7h16NS&expires_in=2592000&token_type=Bearer&scope=read&state=S39Mph8lxdZzE2O7AraydXa3mMdCduJfOXkX8F5Fr6g

排查建议

  1. 修改授权请求的response_mode参数:在provider的authorization.params中添加response_mode: "query",让Sketchfab将授权结果(包括state)放在URL的query参数而非hash中。服务器端无法读取URL hash部分的内容,这是当前错误的核心原因。修改后的authorization配置如下:

    authorization: {
      url: SKETCHFAB_AUTHORIZE_URL,
      params: {
        scope: "read",
        response_type: "token",
        response_mode: "query"
      },
    },
    

    注意:需确认Sketchfab OAuth2服务支持response_mode=query参数

  2. 自定义客户端回调处理:如果Sketchfab不支持修改response_mode,需要在客户端处理hash参数:

    • 创建自定义的回调页面(如pages/auth/callback/sketchfab.tsx)
    • 在页面中用JavaScript读取URL hash中的参数,将其转换为query参数后,跳转至NextAuth的官方callback接口(/api/auth/callback/sketchfab)
    • 示例代码片段:
      useEffect(() => {
        const hash = window.location.hash.slice(1);
        if (hash) {
          const params = new URLSearchParams(hash);
          window.location.href = `/api/auth/callback/sketchfab?${params.toString()}`;
        }
      }, []);
      
  3. 检查redirect_uri一致性:确认Sketchfab开发者后台配置的redirect_uri,与NextAuth中自动生成的callbackUrl(日志中显示的callbackUrl字段)完全一致,包括协议(http/https)、域名、路径,无大小写或斜杠差异。

  4. 调整state校验配置:临时尝试将checks: ["state"]改为checks: [](仅用于排查),如果错误消失,说明问题确实出在state参数的传递环节,但不建议长期关闭校验,需优先解决参数传递问题。

  5. 排查Cookie问题:检查__Secure-next-auth.state cookie的SameSite、Domain等配置,确保在Vercel部署环境下,服务器能正常读取该cookie(可在浏览器开发者工具的Application面板查看cookie属性)。

内容的提问来源于stack exchange,提问作者user21624424

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 07:09:57