You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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重定向逻辑做了安全性升级,主要可能是这几点:

  1. 两次独立的Custom Tabs调用(prompt=noneprompt=login)触发了Chrome的重复会话拦截,导致重定向Intent无法正常传递回应用
  2. 新版本加强了自定义Scheme的验证,当重定向URL的Scheme注册不规范或存在会话冲突时,会阻止Intent发送
  3. 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=noneprompt=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. 优先测试方案1的会话复用,看是否能解决白屏问题
  2. 检查Manifest中Scheme的注册是否符合规范
  3. 用Stetho重新捕获网络请求,确认authorization.ping请求是否正常完成,重定向Intent是否被正确接收

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

火山引擎 最新活动