You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用oauth2_client包无法正确跳转至指定redirectUri

问题原因

flutter_web_auth_2的CallbackActivity完成授权后,只会将应用从后台唤起回到发起授权的栈顶页面(即HomePage),并不会自动触发GoRouter的deeplink路由跳转。虽然授权成功拿到了token,但redirectUri的查询参数不会自动传递给路由,导致无法跳转到AboutPage。

解决方案

方案一:手动处理授权结果并导航(推荐)

既然已经确认oauth2Helper能成功获取token,可直接从授权回调的响应中提取realmId,然后手动调用GoRouter导航到AboutPage:

修改BooksmartOAuthHelper的authenticateOAuth2Helper方法:

void authenticateOAuth2Helper(String accountingApp, BuildContext context) async {
  switch (accountingApp) {
    case 'Quickbooks':
      IntuitOAuth2Client client = IntuitOAuth2Client(
        redirectUri: 'https://booksmart-6870c.web.app/about',
        customUriScheme: 'https'
      );

      oauth2Helper = OAuth2Helper(
        client,
        grantType: OAuth2Helper.authorizationCode,
        clientId: intuitClientId,
        clientSecret: intuitClientSecret,
        scopes: ['com.intuit.quickbooks.accounting', 'com.intuit.quickbooks.payment'],
      );

      // 发起授权并获取token
      final tokenResponse = await oauth2Helper!.fetchToken();
      // 从tokenResponse的附加参数中提取realmId
      if (tokenResponse.additionalParameters != null) {
        final realmId = tokenResponse.additionalParameters!['realmId'];
        if (realmId != null) {
          quickbooksRealmId = realmId;
          // 手动导航到AboutPage
          if (context.mounted) {
            GoRouter.of(context).push('/about?realmId=$realmId');
          }
        }
      }
    default:
      throw UnimplementedError('$accountingApp is not supported yet');
  }
}

方案二:调整AndroidManifest配置,让deeplink直接触发路由

将deeplink的intent-filter移回MainActivity,同时保留CallbackActivity的配置仅处理授权回调:

<manifest ...>
    <application ...>
        <activity android:name=".MainActivity" ...>
            <!-- 添加deeplink的intent-filter -->
            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="https" 
                    android:host="booksmart-6870c.web.app" 
                    android:pathPrefix="/about" />
            </intent-filter>
        </activity>
        <meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
        <activity android:name="com.linusu.flutter_web_auth_2.CallbackActivity" android:exported="true">
            <intent-filter android:label="flutter_web_auth_2">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="https" 
                    android:host="booksmart-6870c.web.app" 
                    android:pathPrefix="/about" />
            </intent-filter>
        </activity>
</manifest>

同时在main.dart中确保GoRouter能处理deeplink:

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: router,
    );
  }
}

额外注意

  • 方案一更直接,不需要依赖系统deeplink的跳转逻辑,避免了Activity配置冲突的问题。
  • 若使用方案二,需确保assetlinks.json配置正确,且Android设备已验证App Link(可通过adb shell dumpsys package domain-preferred-apps命令验证)。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 15:53:13