Flutter自动登录插件autologin_web的使用
Flutter自动登录插件autologin_web的使用
autologin_web 是 autologin 包在 Web 平台上的实现。此包已被推荐为受支持的插件,因此你可以在项目中直接使用 autologin,而无需手动将其添加到 pubspec.yaml 文件中。
使用说明
如果你只是想使用 autologin 包的功能,那么你可以直接导入并使用它。但是,如果你想直接使用 autologin_web 包中的某些 API,则需要将其添加到 pubspec.yaml 文件中。
以下是一个完整的示例,展示了如何在 Flutter 应用程序中使用 autologin_web 插件来实现自动登录功能。
import 'dart:async';
import 'package:autologin/autologin.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const DemoFrame());
}
/// 这个框架只是为了确保 DemoPage 可以显示一个 Snackbar
class DemoFrame extends StatelessWidget {
const DemoFrame({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Autologin-Plugin 示例应用'),
),
body: const SingleChildScrollView(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 24),
child: Align(
child: SizedBox(
width: 400,
child: DemoPage(),
),
),
),
),
);
}
}
class DemoPage extends StatefulWidget {
const DemoPage({super.key});
@override
State<DemoPage> createState() => _DemoPageState();
}
/// 大多数这些状态字段只是为了调试正在发生的事情
class _DemoPageState extends State<DemoPage> {
bool? isPlatformSupported;
String? usernameNote;
String? passwordNote;
bool obscurePassword = true;
final usernameController = TextEditingController();
final passwordController = TextEditingController();
String loginToken = 'Loading...';
@override
void initState() {
super.initState();
unawaited(initPlatformState());
usernameController.addListener(resetUsernameNote);
passwordController.addListener(resetPasswordNote);
AutologinPlugin.setup(
domain: 'rekire.github.io',
appId: 'eu.rekisoft.flutter.autologin',
appName: 'Autologin Demo',
);
AutologinPlugin.requestLoginToken().then((value) async {
if (value != null) {
setState(() => loginToken = value);
} else {
final hasZeroTouchSupport = (await AutologinPlugin.performCompatibilityChecks()).hasZeroTouchSupport;
setState(() => loginToken = hasZeroTouchSupport ? '这是首次应用启动' : '平台不受支持');
if (hasZeroTouchSupport) {
await AutologinPlugin.saveLoginToken('首次启动 ${DateTime.now()}');
}
}
}).onError((error, stackTrace) {
setState(() => loginToken = error.toString());
});
}
@override
void dispose() {
super.dispose();
usernameController.removeListener(resetUsernameNote);
passwordController.removeListener(resetPasswordNote);
}
// 平台消息是异步的,所以我们初始化在一个异步方法中。
Future<void> initPlatformState() async {
final isSupported = await AutologinPlugin.isPlatformSupported;
setState(() => isPlatformSupported = isSupported);
}
void resetUsernameNote() {
setState(() => usernameNote = null);
}
void resetPasswordNote() {
setState(() => passwordNote = null);
}
Future<void> requestCredentials() async {
final credentials = await AutologinPlugin.requestCredentials();
if (mounted) {
setState(() {
if (credentials?.username != null) {
usernameController.text = credentials!.username!;
usernameNote = null;
} else {
usernameController.text = '';
usernameNote = 'API 没有提供用户名';
}
if (credentials?.password != null) {
passwordController.text = credentials!.password!;
passwordNote = null;
} else {
passwordController.text = '';
passwordNote = 'API 没有提供密码';
}
});
}
}
Future<void> saveCredentials() async {
final success = await AutologinPlugin.saveCredentials(
Credential(username: usernameController.text, password: passwordController.text, domain: 'rekire.github.io'),
);
if (!success && mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('保存凭证失败!'),
),
);
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
if (isPlatformSupported != true)
const Padding(
padding: EdgeInsets.only(bottom: 16),
child: Text('⚠️ 此浏览器或平台不受支持 ⚠️'),
),
TextFormField(
controller: usernameController,
textInputAction: TextInputAction.next,
autofillHints: const [AutofillHints.username],
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: '用户名',
helperText: usernameNote,
),
onFieldSubmitted: (_) => saveCredentials(),
),
const SizedBox(height: 16),
TextFormField(
controller: passwordController,
obscureText: obscurePassword,
textInputAction: TextInputAction.send,
keyboardType: TextInputType.visiblePassword,
autofillHints: const [AutofillHints.password],
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: '密码',
helperText: passwordNote,
suffixIcon: IconButton(
icon: Icon(obscurePassword ? Icons.visibility : Icons.visibility_off),
onPressed: () {
setState(() => obscurePassword = !obscurePassword);
},
tooltip: obscurePassword ? '显示密码' : '隐藏密码',
),
),
onFieldSubmitted: (_) => saveCredentials(),
),
const SizedBox(height: 16),
FilledButton(
onPressed: isPlatformSupported == true ? saveCredentials : null,
child: const Text('保存凭证'),
),
const SizedBox(height: 8),
OutlinedButton(
onPressed: () {
usernameController.text = 'Some-Username';
passwordController.text = r'Example-P@§$w0rd!';
},
child: const Text('输入示例数据'),
),
const SizedBox(height: 8),
OutlinedButton(
onPressed: isPlatformSupported == true ? requestCredentials : null,
child: const Text('请求登录数据'),
),
const SizedBox(height: 8),
Text('登录令牌: $loginToken'),
],
);
}
}
代码解释
-
导入依赖:
import 'package:autologin/autologin.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -
主入口点:
void main() { runApp(const DemoFrame()); } -
DemoFrame:
class DemoFrame extends StatelessWidget { const DemoFrame({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Autologin-Plugin 示例应用'), ), body: const SingleChildScrollView( padding: EdgeInsets.symmetric(vertical: 8, horizontal: 24), child: Align( child: SizedBox( width: 400, child: DemoPage(), ), ), ), ), ); } } -
DemoPage:
class DemoPage extends StatefulWidget { const DemoPage({super.key}); @override State<DemoPage> createState() => _DemoPageState(); } class _DemoPageState extends State<DemoPage> { // 状态字段 bool? isPlatformSupported; String? usernameNote; String? passwordNote; bool obscurePassword = true; final usernameController = TextEditingController(); final passwordController = TextEditingController(); String loginToken = 'Loading...'; @override void initState() { super.initState(); unawaited(initPlatformState()); usernameController.addListener(resetUsernameNote); passwordController.addListener(resetPasswordNote); AutologinPlugin.setup( domain: 'rekire.github.io', appId: 'eu.rekisoft.flutter.autologin', appName: 'Autologin Demo', ); AutologinPlugin.requestLoginToken().then((value) async { if (value != null) { setState(() => loginToken = value); } else { final hasZeroTouchSupport = (await AutologinPlugin.performCompatibilityChecks()).hasZeroTouchSupport; setState(() => loginToken = hasZeroTouchSupport ? '这是首次应用启动' : '平台不受支持'); if (hasZeroTouchSupport) { await AutologinPlugin.saveLoginToken('首次启动 ${DateTime.now()}'); } } }).onError((error, stackTrace) { setState(() => loginToken = error.toString()); }); } @override void dispose() { super.dispose(); usernameController.removeListener(resetUsernameNote); passwordController.removeListener(resetPasswordNote); } // 初始化平台状态 Future<void> initPlatformState() async { final isSupported = await AutologinPlugin.isPlatformSupported; setState(() => isPlatformSupported = isSupported); } // 重置用户名备注 void resetUsernameNote() { setState(() => usernameNote = null); } // 重置密码备注 void resetPasswordNote() { setState(() => passwordNote = null); } // 请求凭证 Future<void> requestCredentials() async { final credentials = await AutologinPlugin.requestCredentials(); if (mounted) { setState(() { if (credentials?.username != null) { usernameController.text = credentials!.username!; usernameNote = null; } else { usernameController.text = ''; usernameNote = 'API 没有提供用户名'; } if (credentials?.password != null) { passwordController.text = credentials!.password!; passwordNote = null; } else { passwordController.text = ''; passwordNote = 'API 没有提供密码'; } }); } } // 保存凭证 Future<void> saveCredentials() async { final success = await AutologinPlugin.saveCredentials( Credential(username: usernameController.text, password: passwordController.text, domain: 'rekire.github.io'), ); if (!success && mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('保存凭证失败!'), ), ); } } @override Widget build(BuildContext context) { return Column( children: [ // 显示平台支持信息 if (isPlatformSupported != true) const Padding( padding: EdgeInsets.only(bottom: 16), child: Text('⚠️ 此浏览器或平台不受支持 ⚠️'), ), // 用户名输入框 TextFormField( controller: usernameController, textInputAction: TextInputAction.next, autofillHints: const [AutofillHints.username], decoration: InputDecoration( border: const OutlineInputBorder(), labelText: '用户名', helperText: usernameNote, ), onFieldSubmitted: (_) => saveCredentials(), ), const SizedBox(height: 16), // 密码输入框 TextFormField( controller: passwordController, obscureText: obscurePassword, textInputAction: TextInputAction.send, keyboardType: TextInputType.visiblePassword, autofillHints: const [AutofillHints.password], decoration: InputDecoration( border: const OutlineInputBorder(), labelText: '密码', helperText: passwordNote, suffixIcon: IconButton( icon: Icon(obscurePassword ? Icons.visibility : Icons.visibility_off), onPressed: () { setState(() => obscurePassword = !obscurePassword); }, tooltip: obscurePassword ? '显示密码' : '隐藏密码', ), ), onFieldSubmitted: (_) => saveCredentials(), ), const SizedBox(height: 16), // 保存凭证按钮 FilledButton( onPressed: isPlatformSupported == true ? saveCredentials : null, child: const Text('保存凭证'), ), const SizedBox(height: 8), // 输入示例数据按钮 OutlinedButton( onPressed: () { usernameController.text = 'Some-Username'; passwordController.text = r'Example-P@§$w0rd!'; }, child: const Text('输入示例数据'), ), const SizedBox(height: 8), // 请求登录数据按钮 OutlinedButton( onPressed: isPlatformSupported == true ? requestCredentials : null, child: const Text('请求登录数据'), ), const SizedBox(height: 8), // 显示登录令牌 Text('登录令牌: $loginToken'), ], ); } }
更多关于Flutter自动登录插件autologin_web的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自动登录插件autologin_web的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用autologin_web插件来实现自动登录功能的示例代码。autologin_web插件通常用于在Web平台上通过URL参数自动填充登录表单。
首先,确保你已经在pubspec.yaml文件中添加了autologin_web依赖:
dependencies:
flutter:
sdk: flutter
autologin_web: ^最新版本号 # 请替换为实际最新版本号
然后运行flutter pub get来安装依赖。
接下来,让我们编写一个示例应用,展示如何使用autologin_web插件。
main.dart
import 'package:flutter/material.dart';
import 'package:autologin_web/autologin_web.dart';
import 'dart:html' as html;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter AutoLogin Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: AutoLoginPage(),
);
}
}
class AutoLoginPage extends StatefulWidget {
@override
_AutoLoginPageState createState() => _AutoLoginPageState();
}
class _AutoLoginPageState extends State<AutoLoginPage> {
String _username = '';
String _password = '';
@override
void initState() {
super.initState();
_listenForAutoLogin();
}
void _listenForAutoLogin() {
AutoLoginWeb().listen((data) {
setState(() {
_username = data?.username ?? '';
_password = data?.password ?? '';
});
print('Auto login data received: ${data?.toString()}');
// 在这里你可以添加自动登录的逻辑,比如调用登录API
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Auto Login Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
decoration: InputDecoration(labelText: 'Username'),
controller: TextEditingController(text: _username),
),
SizedBox(height: 16),
TextField(
obscureText: true,
decoration: InputDecoration(labelText: 'Password'),
controller: TextEditingController(text: _password),
),
SizedBox(height: 24),
ElevatedButton(
onPressed: () {
// 在这里添加实际的登录逻辑
print('Logging in with username: $_username, password: $_password');
},
child: Text('Login'),
),
],
),
),
);
}
}
说明
- 依赖添加:在
pubspec.yaml中添加autologin_web依赖。 - 监听自动登录数据:在
_AutoLoginPageState的initState方法中,通过AutoLoginWeb().listen来监听URL参数中的自动登录数据。一旦接收到数据,更新UI中的用户名和密码字段。 - UI显示:使用
TextField来显示和编辑用户名和密码。初始时,这些字段会被自动登录数据填充(如果有的话)。 - 登录按钮:点击登录按钮时,可以在控制台打印出用户名和密码,实际项目中应替换为调用登录API的逻辑。
注意事项
- 确保你的应用运行在Web平台上,因为
autologin_web插件只支持Web。 - 自动登录数据通常通过URL参数传递,例如
https://yourapp.com/?username=test&password=1234。 - 出于安全考虑,自动登录功能应谨慎使用,尤其是在生产环境中,避免敏感信息泄露。
希望这个示例代码能帮助你理解如何在Flutter项目中使用autologin_web插件实现自动登录功能。

