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
相关产品推荐
相关产品推荐

