Chrome从61升级至72导致Android端Chrome Custom Tabs OAuth登录故障
解决Chrome 72+版本中Custom Tabs OAuth登录白屏卡住的问题
嘿,我刚好遇到过类似的Chrome Custom Tabs OAuth升级兼容问题,针对你描述的Chrome从61升级到72.0.3626.76后,prompt=login环节出现白屏无响应、应用收不到Intent的情况,我来分享下排查思路和可行的解决方案:
先明确问题核心
- 仅在Chrome 72+作为默认浏览器时出现,回退旧版或切换Firefox/Opera正常
- 流程卡在用户输入凭证点击登录后,最后一个
authorization.ping请求被取消 - 临时添加
prompt=consent能恢复流程,但每次登录都会弹出授权确认页,影响体验
可能的触发原因
Chrome 72版本对Custom Tabs的会话管理、OAuth重定向逻辑做了安全性升级,主要可能是这几点:
- 两次独立的Custom Tabs调用(
prompt=none和prompt=login)触发了Chrome的重复会话拦截,导致重定向Intent无法正常传递回应用 - 新版本加强了自定义Scheme的验证,当重定向URL的Scheme注册不规范或存在会话冲突时,会阻止Intent发送
prompt=login请求在Chrome 72中需要更明确的会话标识,否则会被判定为无效请求
具体解决方案
方案1:复用Custom Tabs会话,避免会话冲突
Chrome Custom Tabs支持会话复用,两次登录请求用同一个会话可以避免拦截,代码调整如下:
// 先初始化会话相关变量 private CustomTabsSession customTabsSession; private CustomTabsClient customTabsClient; // 绑定Chrome Custom Tabs服务 private void bindCustomTabsService() { CustomTabsClient.bindCustomTabsService(this, "com.android.chrome", new CustomTabsServiceConnection() { @Override public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) { customTabsClient = client; customTabsClient.warmup(0L); // 提前预热提升性能 // 创建会话,可监听状态回调 customTabsSession = customTabsClient.newSession(new CustomTabsCallback()); } @Override public void onServiceDisconnected(ComponentName name) { customTabsClient = null; customTabsSession = null; } }); } // 复用会话打开Custom Tab private void openCustomTabWithSession(String url) { if (customTabsSession == null) { // 会话未初始化时降级为普通调用 CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); builder.build().launchUrl(this, Uri.parse(url)); return; } // 使用已有的会话创建Intent CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(customTabsSession); CustomTabsIntent customTabsIntent = builder.build(); customTabsIntent.launchUrl(this, Uri.parse(url)); }
之后两次登录请求都调用openCustomTabWithSession,复用同一个Chrome会话,减少冲突概率。
方案2:优化OAuth请求逻辑,避免重复prompt冲突
不要拆分prompt=none和prompt=login两次请求,调整为:
- 第一次发起
prompt=none请求,若后端返回400(需重新登录),直接发起带prompt=login+ 完整PKCE参数(code_verifier/code_challenge)的请求 - 同时务必检查AndroidManifest中自定义Scheme的注册是否规范,确保重定向Intent能被正确捕获:
<activity android:name=".SignInActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 替换成你的自定义Scheme --> <data android:scheme="your-app-oauth-scheme" /> </intent-filter> </activity>
另外,确认code_verifier的生成完全符合RFC 7636标准,Chrome 72对PKCE参数的校验更严格。
方案3:设置PendingIntent模板确保Intent传递
通过setPendingIntentTemplate强制Chrome将重定向参数传递回应用,代码示例:
// 创建PendingIntent模板,用于接收重定向参数 Intent redirectIntent = new Intent(this, SignInActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity( this, 0, redirectIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); // 在CustomTabsIntent builder中设置模板 CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); // 替换成你的重定向Scheme前缀 builder.setPendingIntentTemplate(Uri.parse("your-app-oauth-scheme://"), pendingIntent); CustomTabsIntent customTabsIntent = builder.build(); customTabsIntent.launchUrl(SignInActivity.this, getURL(PROMPT_LOGIN, authCode));
这个方法能确保Chrome在重定向时正确填充参数并发送Intent到你的应用。
方案4:优化临时prompt=consent的体验
如果暂时需要保留prompt=consent,可以在OAuth服务端配置静默授权规则:当用户已经授权过且凭证未过期时,自动跳过确认页;或者检查Chrome官方文档,确认是否有新的参数可以替代prompt=consent,避免每次都显示授权界面。
验证步骤
- 优先测试方案1的会话复用,看是否能解决白屏问题
- 检查Manifest中Scheme的注册是否符合规范
- 用Stetho重新捕获网络请求,确认
authorization.ping请求是否正常完成,重定向Intent是否被正确接收
内容的提问来源于stack exchange,提问作者Hector




