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

Expo与Amazon Cognito集成Web端认证失败问题排查

问题分析

你的问题核心是Expo Auth Session在Web端无法正确处理AWS Cognito的授权回调,主要原因有两点:

  • Web端默认的makeRedirectUri生成地址未匹配专门的回调页面,导致重定向后无法触发Auth Session的消息通信
  • Expo Router路由结构下缺少专门的回调页面处理授权响应,弹窗无法向主窗口传递成功信号,主窗口始终认为弹窗被手动关闭(返回dismiss类型响应)
解决方案

1. 配置正确的重定向URI并更新Cognito客户端

显式指定Web端回调路径,建议在Expo Router中创建/auth/callback专属页面,修改redirectUri生成逻辑:

const redirectUri = makeRedirectUri({
  // Web端指定回调路径,移动端自动使用默认scheme
  web: `${window.location.origin}/auth/callback`,
});

同时登录AWS Cognito控制台,将上述Web端回调URI添加到用户池应用客户端的回调URL和注销URL列表(开发环境注意使用http://localhost:8080或实际开发端口)。

2. 创建Expo Router回调页面

在app/auth/callback.tsx中创建如下页面,用于处理授权响应并关闭弹窗:

import { useAuthRequest, makeRedirectUri } from "expo-auth-session";
import { useEffect } from "react";
import { View } from "react-native";

const clientId = process.env.EXPO_PUBLIC_COGNITO_CLIENT_ID!;
const userPoolUrl = process.env.EXPO_PUBLIC_COGNITO_USER_POOL!;

export default function AuthCallback() {
  const discoveryDocument = {
    authorizationEndpoint: `${userPoolUrl}/oauth2/authorize`,
    tokenEndpoint: `${userPoolUrl}/oauth2/token`,
    revocationEndpoint: `${userPoolUrl}/oauth2/revoke`,
  };

  const [, response] = useAuthRequest(
    {
      clientId,
      responseType: "code",
      redirectUri: makeRedirectUri({ web: `${window.location.origin}/auth/callback` }),
      usePKCE: true,
    },
    discoveryDocument
  );

  useEffect(() => {
    // 获取到响应后关闭弹窗,Web端自动通过postMessage通知主窗口
    if (response) {
      window.close();
    }
  }, [response]);

  return <View />;
}

该页面的作用是在授权回调后触发Auth Session响应处理,关闭弹窗并让主窗口接收到正确的success类型响应。

3. 调整主页面逻辑

确保主页面useEffect中正确处理success响应的token交换逻辑:

React.useEffect(() => {
  const exchangeFn = async (exchangeTokenReq: AccessTokenRequestConfig) => {
    try {
      const exchangeTokenResponse = await exchangeCodeAsync(
        exchangeTokenReq,
        discoveryDocument
      );
      setAuthTokens(exchangeTokenResponse);
    } catch (error) {
      console.error("Token交换失败:", error);
    }
  };
  if (response) {
    console.log("响应类型:", response.type);
    if (response.type === "error") {
      Alert.alert(
        "认证失败",
        response.params.error_description || "发生未知错误"
      );
      return;
    }
    if (response.type === "success" && request?.codeVerifier) {
      exchangeFn({
        clientId,
        code: response.params.code,
        redirectUri,
        extraParams: {
          code_verifier: request.codeVerifier,
        },
      });
    }
  }
}, [discoveryDocument, request, response]);

4. 开发环境额外配置

使用expo start --web启动开发服务时,确保app/_layout.tsx的默认路由栈配置能正确匹配/auth/callback路径(默认Expo Router配置已支持嵌套路由)。

移动端正常的原因

移动端Expo Go使用App Scheme作为重定向URI,Auth Session可直接通过App深链接机制捕获授权响应,无需额外回调页面;而Web端依赖浏览器弹窗的postMessage通信,必须通过专属回调页面完成响应传递,否则主窗口会判定弹窗被手动关闭,返回dismiss类型响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:23:22