React Native 无法使用Expo通过Twitter进行身份验证

ifmq2ha2  于 2023-01-05  发布在  React
关注(0)|答案(1)|浏览(168)

我正在尝试使用OAuth2在我的React-Native/Expo应用程序上通过Twitter进行身份验证,使用的是expo-auth-session包(Expo的Twitter OAuth指南)。
Twitter OAuth2流程分两步工作:首先,用户授权应用访问其帐户,帐户返回一个代码,然后我们用该代码交换访问令牌。我被困在第二步。每当我尝试用代码交换令牌时,使用expo的 * exchangeCodeAsync * 函数,并使用以下参数:

exchangeCodeAsync({
    clientId: '<CLIENT_ID>',
    redirectUri: makeRedirectUri({
        scheme: 'my.app',
        useProxy
    }),
    code: response.params.code,
    extraParams: {
        client_id: "<CLIENT_ID>",
        code_verifier: request?.codeVerifier || '',
        redirect_uri: makeRedirectUri({
            scheme: 'my.app',
            useProxy
        }),
        grant_type: "authorization_code",
    },
}, discovery)

我得到这个错误:

Possible Unhandled Promise Rejection (id: 0):
SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON

我所理解的是,该函数在后台向Twitter API的/oauth2/token路由发出请求,但由于某个错误的参数,它返回了一个HTML错误代码:
出了点问题,但别担心--让我们再试一次。
由于错误信息是如此模糊,我不知道我的请求出了什么问题。
我假设既然我已经完成了授权步骤,redirect_uri已经正确配置,我还根据Twitter's documentation确保了"code_verifier"和"code"字段的格式有效。
下面是一个Expo Snack,展示了我正在使用的完整App.js设置(我还使用自定义方案配置了app.json)
https://snack.expo.dev/lWYp82Pwq

68bkxrlz

68bkxrlz1#

我能够使用一些拼凑起来的代码路径获得一个工作的Twitter登录:

const twitterDiscovery = {
  authorizationEndpoint: "https://twitter.com/i/oauth2/authorize",
  tokenEndpoint: "https://api.twitter.com/2/oauth2/token",
}
...
    const redirectUri = AuthSession.makeRedirectUri({
      scheme: APP_URI_SCHEME,
      useProxy: true,
    })
    const reqConfig = {
      clientId: TWITTER_CLIENT_ID,
      redirectUri,
      usePKCE: true,
      scopes: twitterScopes,
    }
    const authReq = new AuthRequest(reqConfig)
    const authUrl = await authReq.makeAuthUrlAsync(twitterDiscovery)
    const loginResult = await AuthSession.startAsync({ authUrl, returnUrl })
    if (loginResult.type !== "success") {
      throw new Error("...")
    }
    const tokenRequest = new AccessTokenRequest({
      ...reqConfig,
      code: loginResult.params.code,
      extraParams: {
        code_verifier: authReq.codeVerifier,
      },
    })
    const tokenResult = await tokenRequest.performAsync(twitterDiscovery)

这显然可以清理一点,但它似乎是功能,所以我想张贴,即使它不漂亮。

相关问题