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

如何通过WebView登录并捕获Access Token后返回移动端操作

使用WebView完成登录并捕获Access Token的实现方案

核心思路

通过webview_flutter加载第三方登录页面,监听页面的URL跳转事件。当登录成功后,后端会重定向到预配置的自定义Scheme回调URL(如yourapp://callback?access_token=xxx),此时捕获URL中的access_token参数,关闭WebView并将Token返回给原生页面,继续后续业务操作。


具体实现步骤

1. 添加依赖

在项目的pubspec.yaml中引入webview_flutter包:

dependencies:
  flutter:
    sdk: flutter
  webview_flutter: ^4.4.0 # 可替换为最新稳定版

执行flutter pub get安装依赖。

2. 构建登录WebView页面

创建一个单独的WebView页面,负责加载登录页、监听URL跳转并提取Token:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class LoginWebView extends StatefulWidget {
  final String loginUrl; // 第三方登录页面地址
  final String callbackScheme; // 自定义回调Scheme,如"yourapp"

  const LoginWebView({
    super.key,
    required this.loginUrl,
    required this.callbackScheme,
  });

  @override
  State<LoginWebView> createState() => _LoginWebViewState();
}

class _LoginWebViewState extends State<LoginWebView> {
  late final WebViewController _webController;

  @override
  void initState() {
    super.initState();
    _webController = WebViewController()
      // 允许JavaScript执行(部分登录页依赖JS)
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(
        NavigationDelegate(
          onNavigationRequest: (NavigationRequest request) {
            // 检测是否跳转到自定义回调URL
            if (request.url.startsWith("${widget.callbackScheme}://")) {
              final uri = Uri.parse(request.url);
              final accessToken = uri.queryParameters['access_token'];
              
              if (accessToken != null) {
                // 关闭WebView,将Token返回给上一级页面
                Navigator.pop(context, accessToken);
              }
              // 阻止实际跳转,避免打开外部应用
              return NavigationDecision.prevent;
            }
            // 其他URL正常跳转
            return NavigationDecision.navigate;
          },
        ),
      )
      // 加载登录页面
      ..loadRequest(Uri.parse(widget.loginUrl));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('账号登录')),
      body: WebViewWidget(controller: _webController),
    );
  }
}

3. 调用WebView并处理返回的Token

在需要触发登录的页面,通过Navigator.push打开WebView,等待返回的Token并执行后续操作:

// 示例:在首页的登录按钮点击事件中触发
void _triggerLogin() async {
  final accessToken = await Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => LoginWebView(
        loginUrl: 'https://your-auth-server.com/login', // 替换为实际登录地址
        callbackScheme: 'yourapp', // 替换为你配置的自定义Scheme
      ),
    ),
  );

  if (accessToken != null) {
    // 拿到Token后的业务逻辑:存储Token、请求用户信息等
    print('获取到Access Token: $accessToken');
    // 示例:存储到本地
    // await SharedPreferences.getInstance().then((prefs) => prefs.setString('token', accessToken));
    // 跳转首页或用户中心
    // Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => HomePage()));
  }
}

平台配置注意事项

为了让自定义Scheme的回调URL能被WebView识别,需要在Android和iOS项目中配置Scheme:

  • Android:在android/app/src/main/AndroidManifest.xml的<activity>标签内添加intent-filter:
    <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="yourapp" />
    </intent-filter>
    
  • iOS:在ios/Runner/Info.plist中添加以下配置:
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>yourapp</string> <!-- 自定义Scheme -->
            </array>
        </dict>
    </array>
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 02:37:37