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

Flutter WebView实现App启动后自动登录指定网站的方法

在Flutter中实现WebView自动登录目标网站

要实现Flutter WebView加载网站时自动完成登录,我们可以借助webview_flutter包,结合网站提供的frame-login接口完成认证。以下是具体实现步骤:

1. 添加依赖

在项目的pubspec.yaml中添加WebView依赖:

dependencies:
  flutter:
    sdk: flutter
  webview_flutter: ^4.4.0 # 建议使用最新稳定版本

2. 核心实现逻辑

通过WebView的初始化回调,在页面加载完成后执行JavaScript代码,调用网站的登录接口携带authToken完成认证,之后刷新页面加载已登录状态的内容。

3. 完整代码实现

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

class AuthenticatedWebView extends StatefulWidget {
  final String authToken;

  const AuthenticatedWebView({super.key, required this.authToken});

  @override
  State<AuthenticatedWebView> createState() => _AuthenticatedWebViewState();
}

class _AuthenticatedWebViewState extends State<AuthenticatedWebView> {
  late WebViewController _controller;
  bool _hasLoggedIn = false;

  @override
  void initState() {
    super.initState();
    _setupWebViewController();
  }

  void _setupWebViewController() {
    _controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(
        NavigationDelegate(
          onPageFinished: (url) async {
            // 仅在未登录时执行登录逻辑
            if (!_hasLoggedIn) {
              await _executeWebLogin();
            }
          },
        ),
      )
      // 先加载网站主页,触发登录逻辑
      ..loadRequest(Uri.parse('https://englishin7boxes.com'));
  }

  Future<void> _executeWebLogin() async {
    try {
      // 构造登录请求的JS代码,转义Token中的特殊字符避免语法错误
      final loginJs = '''
        fetch('https://englishin7boxes.com/api/frame-login', {
          method: 'POST',
          headers: {
            'Authorization': 'Bearer ${widget.authToken.replaceAll("'", "\\'")}',
            'Content-Type': 'application/json'
          }
        })
        .then(res => {
          if (res.ok) {
            window.flutterBridge.postMessage('login_success');
          } else {
            window.flutterBridge.postMessage('login_failed');
          }
        })
        .catch(err => window.flutterBridge.postMessage('login_failed'));
      ''';

      // 执行JS登录请求
      await _controller.runJavaScript(loginJs);

      // 监听JS返回的登录结果
      _controller.addJavaScriptChannel(
        'flutterBridge',
        onMessageReceived: (message) {
          if (message.message == 'login_success') {
            setState(() => _hasLoggedIn = true);
            // 刷新页面以加载已登录内容
            _controller.reload();
          } else {
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(content: Text('Web端登录失败,请重试')),
            );
          }
        },
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('登录出错:$e')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('English in 7 Boxes')),
      body: WebViewWidget(controller: _controller),
    );
  }
}

4. 关键细节说明

  • JavaScript权限:必须开启JavaScriptMode.unrestricted,否则无法执行fetch请求完成登录。
  • Token转义:对authToken中的单引号进行转义,避免JS语法错误。
  • 重复登录拦截:用_hasLoggedIn标记登录状态,防止页面刷新后重复调用登录接口。
  • 结果回调:通过JavaScriptChannel将Web端的登录状态同步到Flutter,方便处理UI反馈。

备选方案:通过Cookie注入实现登录

如果网站依赖Cookie维持登录状态,也可以先通过Flutter的HTTP库调用登录接口获取Cookie,再注入到WebView中:

import 'package:http/http.dart' as http;

Future<void> _injectLoginCookie() async {
  final response = await http.post(
    Uri.parse('https://englishin7boxes.com/api/frame-login'),
    headers: {
      'Authorization': 'Bearer ${widget.authToken}',
      'Content-Type': 'application/json',
    },
  );

  if (response.statusCode == 200) {
    final cookies = response.headers['set-cookie'];
    if (cookies != null) {
      // 将Cookie注入WebView
      await _controller.runJavaScript('document.cookie = "$cookies";');
      _controller.reload();
    }
  }
}

该方案适用于网站通过Cookie管理会话的场景,可根据实际情况选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:53:10