React Native Expo-Auth-Session Twitter:为代码验证程序传递的值与代码挑战不匹配

问题描述 投票:0回答:1

我目前正在尝试使用 Twitter 的 v2 API 和 expo-auth-session 为 React Native (Expo) 应用程序构建 Twitter 授权流程。在对用户进行身份验证后,我能够从 Twitter 的 API 接收代码,但在按照文档将代码交换为访问令牌时遇到了问题。我已经构建了一个 React hook 来处理整个 Twitter 身份验证过程,但是登录后,我总是收到此错误

为代码验证者传递的值与代码质询不匹配

这是我的代码片段

import React from "react"
import {
  useAuthRequest,
  CodeChallengeMethod,
  ResponseType,
  makeRedirectUri,
} from "expo-auth-session"
import { SocialLogins, SOCIAL_TOKENS, useGlobalStore } from "@libs/shared"
import { TWITTER_CLIENT_ID, TWITTER_CLIENT_SECRET } from "@env"
import pkceChallenge from "react-native-pkce-challenge"

const { codeChallenge, codeVerifier: code_verifier } = pkceChallenge()

export const useTwitterAuth = () => {
  const { socialAuth, handleSocialAuth, services } = useGlobalStore()

  const discovery = {
    authorizationEndpoint: "https://twitter.com/i/oauth2/authorize",
    tokenEndpoint: "https://twitter.com/i/oauth2/token",
    revocationEndpoint: "https://twitter.com/i/oauth2/revoke",
  }

  const state = "my-state"

  const [, , promptAsync] = useAuthRequest(
    {
      clientId: TWITTER_CLIENT_ID!,
      clientSecret: TWITTER_CLIENT_SECRET,
      // TODO: Refactor
      redirectUri: makeRedirectUri({ scheme: "scheme" }),
      usePKCE: true,
      state,
      scopes: ["tweet.read", "users.read", "offline.access"],
      responseType: ResponseType.Code,
      codeChallengeMethod: CodeChallengeMethod.S256,
      codeChallenge,
    },
    discovery
  )

  const handlePressAsync = async () => {
    const result = await promptAsync()
    if (result.type !== "success") {
      alert("Uh oh, something went wrong")
      return
    }

    const accessCode = result.params?.code as string

    const body = new URLSearchParams({
      code: accessCode,
      grant_type: "authorization_code",
      client_id: TWITTER_CLIENT_ID!,
      state,
      redirect_uri: makeRedirectUri({ scheme: "scheme" }),
      code_verifier,
    }).toString()

    fetch("https://api.twitter.com/2/oauth2/token", {
      method: "POST",
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
      },
      body,
    })
      .then((resp) => resp.json())
      .then((data) => console.log("DATA =>", data))

    handleSocialAuth(SocialLogins.Twitter, true)
    await services.storage.setSocialToken(SOCIAL_TOKENS.Twitter, accessCode)
  }

  const handleAuth = async () => {
    if (socialAuth[SocialLogins.Twitter]) {
      handleSocialAuth(SocialLogins.Twitter, false)
      await services.storage.removeSocialToken(SOCIAL_TOKENS.Twitter)
    } else {
      handlePressAsync()
    }
  }

  React.useEffect(() => {
    const handleHasTwitterUser = async () => {
      const twitterToken = await services.storage.getSocialToken(
        SOCIAL_TOKENS.Twitter
      )

      if (!twitterToken) {
        return
      }
      handleSocialAuth(SocialLogins.Twitter, true)
    }

    handleHasTwitterUser()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  return {
    handleTwitterAuth: handleAuth,
  }
}

这仍然返回以下错误:

Value passed for the code verifier did not match the code challenge 
我已经检查了我使用的react-native-pkce-challenge依赖项是否正在工作,通过检查代码挑战哈希器创建与依赖项完全相同的代码挑战,并且它似乎按预期工作。

如果有人遇到过这个问题,我很乐意听取您的意见。谢谢!

我试图让用户授权我的应用程序代表他们作为 Twitter 用户行事。我已成功收到访问代码,但无法使用 PKCE 将访问代码转换为令牌,因为即使它是正确的,我仍然收到相同的错误。

Value passed for the code verifier did not match the code challenge

react-native twitter expo twitter-oauth expo-auth-session
1个回答
0
投票

我遇到了同样的问题,只是通过使用钩子 useAuthRequest() 返回的请求中包含的 codeVerifier 来修复它,而不是使用react-native-pkce-challenge创建一个新的问题

© www.soinside.com 2019 - 2024. All rights reserved.