Twitter API OAuth 2 访问令牌交换 (APP) - 不再支持此浏览器。 -“语法错误:JSON 解析错误:意外字符:<"

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

我正在我的 React Native 应用程序中实现 X 身份验证流程,借助

expo-auth-session
(仅用于请求授权代码)。

我在尝试将身份验证代码交换为访问令牌时收到错误:语法错误:JSON 解析错误:意外字符:<

目前,使用以下配置获取授权码效果很好:

  const TWITTER_AUTHORIZATION_ENDPOINT = "https://twitter.com/i/oauth2/authorize";
  const TWITTER_TOKEN_ENDPOINT = "https://twitter.com/i/oauth2/token";
  const TWITTER_REVOCATION_ENDPOINT = "https://twitter.com/i/oauth2/revoke";

  const discovery = {
    authorizationEndpoint: TWITTER_AUTHORIZATION_ENDPOINT,
    tokenEndpoint: TWITTER_TOKEN_ENDPOINT,
    revocationEndpoint: TWITTER_REVOCATION_ENDPOINT,
  };

  const redirectUri = makeRedirectUri({ scheme: "my-app" });

  const requestConfig = {
    clientId: CLIENT_ID,
    redirectUri,
    scopes: ["tweet.read", "users.read"],
    usePKCE: true,
  };

以下是钩子向用户提示浏览器的逻辑:

export default function useTwitterAuth() {
  const [
    request,
    response,
    promptAsync,
  ] = useAuthRequest(requestConfig, discovery);

  const handleResponse = useCallback(
    async () => {
      if (response?.type !== "success") return;

      try {
        const { code } = response.params;
        const { codeVerifier } = request;

        console.log({ code });
        console.log({ codeVerifier });

        // ... HERE WE WILL CALL THE ACCESS TOKEN ENDPOINT ...
      } catch (err) {
        console.log(err);
      }
    },
    [response, request]
  );

  useEffect(() => {
    handleResponse();
  }, [handleResponse]);

  return { promptAsync };
}

之后,我尝试了两种获取 Twitter 访问令牌的方法:

  1. 无需 expo-auth-session 直接获取端点:
async function exchangeAccessToken({ code, codeVerifier, redirectUri }) {
  const uri = TWITTER_TOKEN_ENDPOINT;

  const headers = {
    "Content-Type": "application/json",
  };

  const response = await fetch(uri, {
    method: "POST",
    headers,
    body: {
      code,
      client_id: CLIENT_ID,
      grant_type: "authorization_code",
      code_verifier: codeVerifier,
      redirect_uri: redirectUri,
    },
  });

  console.log(response);

  const data = await response.json();

  return data;
}

...

const handleResponse = useCallback(
    async () => {
      if (response?.type !== "success") return;

      try {
        const { code } = response.params;
        const { codeVerifier } = request;

        console.log({ code });
        console.log({ codeVerifier });

        const data = await exchangeAccessToken({
          code,
          codeVerifier,
          redirectUri,
        });

        console.log(data);
      } catch (err) {
        console.log(err); // ERROR: [SyntaxError: JSON Parse error: Unexpected character: <]
      }
    },
    [response, request]
  );
  1. 使用 expo-auth-session 获取端点:
  const handleResponse = useCallback(
    async () => {
      if (response?.type !== "success") return;

      try {
        const { code } = response.params;
        const { codeVerifier } = request;

        console.log({ code });
        console.log({ codeVerifier });

        const exchangeAccessRequest = {
          clientId: CLIENT_ID,
          code,
          redirectUri,
          extraParams: {
            code_verifier: codeVerifier,
          },
        };

        const data = await AuthSession.exchangeCodeAsync(exchangeAccessRequest, discovery);

        console.log(data);
      } catch (err) {
        console.log(err); // SAME ERROR: [SyntaxError: JSON Parse error: Unexpected character: <]
      }
    },
    [response, request]
  );

有什么想法吗?当执行

response.text()
解析 HTML 时,我得到:

<body>
  <div class="errorContainer">
    <img width="46" height="38"
      srcset="https://abs.twimg.com/errors/logo46x38.png 1x, https://abs.twimg.com/errors/[email protected] 2x"
      src="https://abs.twimg.com/errors/logo46x38.png" alt="Twitter" />
    <h1>This browser is no longer supported.</h1>
    <p>
      Please switch to a supported browser to continue using twitter.com. You can see a list of supported browsers in our Help Center.
    </p>
  </div>
</body>

javascript react-native oauth-2.0 expo twitter-oauth
1个回答
0
投票

API 网址不正确。

正确的是:

const discovery = {
  authorizationEndpoint: "https://twitter.com/i/oauth2/authorize",
  tokenEndpoint: "https://api.twitter.com/2/oauth2/token",
  revocationEndpoint: "https://api.twitter.com/2/oauth2/revoke",
  userInfoEndpoint: "https://api.twitter.com/2/users/me",
};
© www.soinside.com 2019 - 2024. All rights reserved.