使用expo-auth-session时,非本地redirectUri下如何重定向回App?
嘿,我来帮你拆解下这个OAuth认证的难题——你遇到的情况其实是很多新手在集成第三方认证时都会碰到的自定义Scheme重定向不被允许的问题,别慌,咱们一步步来解决~
核心问题分析
你当前的困境是:第三方认证平台只允许HTTPS类型的redirect_uri,但这类URI没法直接唤起你的App;而能唤起App的自定义Scheme(比如gecond://)又不在平台的允许列表里。本质上是要解决「HTTPS重定向如何传递令牌回App」的问题,下面给你几个可行的方案:
方案1:配置通用链接/应用链接(推荐长期方案)
这是苹果和安卓官方推荐的「HTTPS链接唤起App」的方式,完美适配第三方平台对HTTPSredirect_uri的要求:
- iOS(通用链接):
- 准备一个你拥有的HTTPS域名,在域名根目录上传
apple-app-site-association文件,内容关联你的App的Team ID和Bundle ID - 在Expo项目的
app.json里配置ios.associatedDomains,添加你的域名(格式:applinks:your-domain.com)
- 准备一个你拥有的HTTPS域名,在域名根目录上传
- Android(应用链接):
- 同样用你的HTTPS域名,在
.well-known目录上传assetlinks.json文件,关联你的App的包名和签名指纹 - 在
app.json里配置android.intentFilters,添加对应的链接过滤规则
- 同样用你的HTTPS域名,在
- 把这个HTTPS域名对应的URI(比如
https://your-domain.com/auth-callback)提交给认证平台,添加到允许的redirect_uri列表里 - 最后在App里用
Linking模块监听这个链接的打开事件,从URL的哈希/参数里提取令牌:import { Linking } from 'expo'; Linking.addEventListener('url', (event) => { const urlParams = new URLSearchParams(event.url.split('#')[1]); const accessToken = urlParams.get('access_token'); // 这里处理拿到令牌后的逻辑 });
方案2:搭建简单的中间跳转页面(快速临时方案)
如果暂时没法配置通用链接,你可以快速搭一个中转页面:
- 用Vercel、Netlify这类免费静态网站平台,部署一个简单的HTML页面,逻辑是:当页面加载时,读取URL里的认证参数(比如
access_token),然后自动跳转到你的自定义Scheme链接,把参数带过去
示例HTML代码:<script> const params = window.location.hash.slice(1); window.location.href = `gecond://auth-callback?${params}`; </script> - 把这个中转页面的HTTPS地址(比如
https://your-middle-page.com/callback)添加到认证平台的允许redirect_uri列表里 - 认证完成后,平台会重定向到这个中转页,中转页再自动唤起你的App并传递令牌
方案3:用Expo AuthSession的代理模式(Expo专属快捷方案)
你用的是Expo的AuthSession,其实它内置了代理模式,可以帮你绕过redirect_uri的限制:
- 调用
AuthSession.startAsync时,开启useProxy选项,Expo会用官方的代理服务器帮你中转重定向,然后把令牌传回App:import * as AuthSession from 'expo-auth-session'; const authUrl = 'https://preprod.autenticacao.gov.pt/oauth/askauthorization?redirect_uri=https://auth.expo.io/your-expo-username/your-app-slug&client_id=123456789&response_type=token&state=UOgf2pE6S0'; const result = await AuthSession.startAsync({ authUrl, redirectUri: AuthSession.makeRedirectUri({ useProxy: true }), }); // 从result里直接获取令牌 if (result.type === 'success') { const accessToken = result.params.access_token; } - 注意:需要先确认认证平台是否允许Expo的代理域名(格式一般是
https://auth.expo.io/...),如果不允许,可能需要先提交这个域名到平台的允许列表
内容的提问来源于stack exchange,提问作者Bruno Oliveira
相关产品推荐
相关产品推荐

