Expo浏览器端Google登录重定向失败问题排查
问题排查:Google登录重定向失败(com.apple.AuthenticationServices.WebAuthenticationSession error 1)
问题现象
通过WebView加载网站授权页实现APP登录,测试Google登录时,完成邮箱、密码及2FA验证后,在重定向回APP/关闭浏览器前弹出错误提示;点击弹窗OK和授权窗口Cancel后,load()函数输出日志:
{"error": "The operation couldn’t be completed. (com.apple.AuthenticationServices.WebAuthenticationSession error 1.)", "type": "cancel", "url": null}
同时出现未处理的Promise拒绝警告,需排查是否为重定向URL错误或其他问题。
核心排查与修复方向
1. 重定向URL配置与代码语法问题
- 先确认
my-app://return自定义URL Scheme已在iOS项目Info.plist的CFBundleURLTypes->CFBundleURLSchemes中正确配置,无拼写错误。 - 检查Google OAuth控制台,确认
my-app://return已添加到授权重定向URI列表,格式、大小写完全匹配。 - 代码中存在语法错误:
encodeURIComponent(encodeURIComponent('my-app://'))的字符串未闭合(缺失单引号),导致URL替换逻辑失效,直接引发重定向异常。
2. WebAuthenticationSession错误解析
com.apple.AuthenticationServices.WebAuthenticationSession error 1对应ASWebAuthenticationSessionErrorCanceledLogin,触发原因可能是:
- 用户主动取消授权流程
- 重定向URI未被系统正确识别,导致流程被判定为中断
- 授权会话启动的URL因语法错误(如上述字符串未闭合)变为无效URL
3. Promise未处理与监听器问题
openAuthSessionAsync返回的Promise被拒绝时,当前catch块为空,这是未处理Promise拒绝警告的直接原因,需补充错误处理逻辑。handleUrl中调用Linking.removeEventListener('url', handleUrlEvent),但监听的函数是handleUrl,函数名不匹配会导致监听器无法正确移除,引发内存泄漏或重复处理问题。
4. WebView与系统认证会话的冲突
当前逻辑在WebView的onShouldStartLoadWithRequest中拦截Google授权URL,再调用openAuthSessionAsync启动系统认证会话,两者可能存在状态冲突:
- 系统认证会话启动后,WebView的回调可能仍在触发,导致流程混乱
- 拦截URL后返回
false阻止WebView加载,但需确保系统认证会话的重定向逻辑不受其他代码干扰
修复后的代码示例
const load = async (url) => { // 修复字符串未闭合的语法错误 authUrl = url.replace( encodeURIComponent(encodeURIComponent('my-app://')), encodeURIComponent(encodeURIComponent('my-app://return')), ); try { // 绑定正确的监听器函数 Linking.addEventListener('url', handleUrl); const res = await openAuthSessionAsync(authUrl); if (!res?.url) { console.log('授权流程未返回有效URL(用户取消或流程中断)'); } else { // 处理授权成功后的逻辑,比如解析token console.log('授权成功,重定向URL:', res.url); } } catch (e) { // 处理Promise拒绝,消除警告并打印错误详情 console.error('授权会话出错:', e); } finally { // 无论成功失败,都移除监听器避免内存泄漏 Linking.removeEventListener('url', handleUrl); } } const handleUrl = ({url}) => { // 处理重定向回APP的URL,比如提取授权码或token console.log('收到重定向URL:', url); // 补充存储token等业务逻辑 } const onShouldStartLoadWithRequest = ({url: loadUrl}) => { if (loadUrl.indexOf('my-app://return') === 0) { // 处理重定向回APP的逻辑 // do storage and other good stuff return false; } if (loadUrl.indexOf('external?provider=Google') > -1) { load(loadUrl); return false; } // 允许其他正常页面加载 return true; } return ( <WebView source={{ uri: authUrl }} onShouldStartLoadWithRequest={onShouldStartLoadWithRequest} originWhitelist={['http', 'https', 'my-app']} onHttpError={(e) => console.log('HTTP错误:', e)} onError={(e) => console.log('WebView加载错误:', e)} /> );
额外验证步骤
- 在iOS设备/模拟器上,直接用Safari打开授权URL,完成Google登录后检查是否能正确重定向回APP,验证自定义URL Scheme有效性。
- 核对Google OAuth控制台的客户端ID、授权范围与APP配置是否一致。
- 开启Xcode控制台日志,查看ASWebAuthenticationSession的详细错误输出,进一步定位问题。
内容的提问来源于stack exchange,提问作者physicsboy
相关产品推荐
相关产品推荐

