Flutter for OpenHarmony 登录认证小指南:用 Flutter 给鸿蒙 App 安上 “安全小锁”✨
哈喽哈喽~在鸿蒙 App 里,登录认证就像给自家房门装一把可爱的小锁,既能挡住不速之客,又能让我们的专属数据乖乖待在里面不跑丢~这次我用 Flutter 搭了一套超实用的登录功能,从粉粉的登录页面到稳稳的身份校验,一步步实现下来,感觉自己像给 App 穿了件安全小外套,安全感直接拉满!这次用 Flutter 给鸿蒙 App 做登录认证,就像搭了一个小小的安全城堡,页面是软软的城门,请求是递进去的身
Flutter for OpenHarmony 登录认证小指南:用 Flutter 给鸿蒙 App 安上 “安全小锁”✨
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
一、写在前面:为什么要做登录认证呀?
哈喽哈喽~在鸿蒙 App 里,登录认证就像给自家房门装一把可爱的小锁,既能挡住不速之客,又能让我们的专属数据乖乖待在里面不跑丢~这次我用 Flutter 搭了一套超实用的登录功能,从粉粉的登录页面到稳稳的身份校验,一步步实现下来,感觉自己像给 App 穿了件安全小外套,安全感直接拉满!
这次的小项目里,我做了三件超重要的小事:
画了一个软乎乎的登录页面,用户名和密码输入框乖乖排排坐
用 dio 给后端发消息,让它帮我们检查身份是不是 “自己人”
用 Bloc 管着登录状态,让 App 随时知道我们是 “已登录的小可爱” 还是 “未登录的小客人”
接下来就跟我一起看看,怎么用 Flutter 给鸿蒙 App 安上这把安全小锁吧~
二、第一步:给 App 画个甜甜的登录页面🎨
登录页面可是用户和 App 打招呼的第一面,当然要做得又可爱又好用啦!我用 Flutter 搭了一个适配鸿蒙设备的登录界面,软圆角的输入框、粉粉的按钮,看着就心情好好~
页面里的小细节可不少哦:用户名和密码输入框都加了小图标,密码框还藏了个小眼睛按钮,页面用了 ScrollView 包起来,就算键盘弹出来,输入框也不会被挡住,超贴心~按钮在加载的时候会变成转圈的小圈圈,用户一看就知道 “哦,正在帮我登录呢”。
完整登录页面代码
dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'auth_bloc.dart';
void main() {
runApp(const LoginApp());
}
class LoginApp extends StatelessWidget {
const LoginApp({super.key});
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => AuthBloc(),
child: MaterialApp(
title: '鸿蒙登录认证',
theme: ThemeData(primarySwatch: Colors.pink),
home: const LoginPage(),
),
);
}
}
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final _usernameController = TextEditingController();
final _passwordController = TextEditingController();
bool _passwordVisible = false;
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 80),
const Text(
'小可爱登录',
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
const SizedBox(height: 40),
// 用户名输入框
TextField(
controller: _usernameController,
decoration: const InputDecoration(
labelText: '用户名',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.person),
),
),
const SizedBox(height: 20),
// 密码输入框
TextField(
controller: _passwordController,
obscureText: !_passwordVisible,
decoration: InputDecoration(
labelText: '密码',
border: const OutlineInputBorder(),
prefixIcon: const Icon(Icons.lock),
suffixIcon: IconButton(
icon: Icon(_passwordVisible ? Icons.visibility : Icons.visibility_off),
onPressed: () {
setState(() {
_passwordVisible = !_passwordVisible;
});
},
),
),
),
const SizedBox(height: 40),
// 登录按钮
BlocBuilder<AuthBloc, AuthState>(
builder: (context, state) {
return ElevatedButton(
onPressed: state is AuthLoading
? null
: () {
context.read<AuthBloc>().add(
LoginSubmitted(
username: _usernameController.text,
password: _passwordController.text,
),
);
},
style: ElevatedButton.styleFrom(padding: const EdgeInsets.symmetric(vertical: 16)),
child: state is AuthLoading
? const CircularProgressIndicator(color: Colors.white)
: const Text('马上登录', style: TextStyle(fontSize: 18)),
);
},
),
// 错误提示
BlocBuilder<AuthBloc, AuthState>(
builder: (context, state) {
if (state is AuthFailure) {
return Padding(
padding: const EdgeInsets.only(top: 20),
child: Text(state.errorMessage, style: const TextStyle(color: Colors.red), textAlign: TextAlign.center),
);
}
return const SizedBox();
},
),
],
),
),
),
);
}
}
三、第二步:用 dio 发个 “身份小纸条”📨
画好页面,接下来就要让 App 和后端说悄悄话啦!我用 dio 写了一个登录请求的小工具,用户输入用户名和密码后,App 会把这些信息打包成一张 “身份小纸条”,发给后端让它帮忙检查~
这个小工具可聪明啦:会先帮我们检查用户名和密码有没有空着,给请求加了 10 秒的小闹钟,还会把请求过程打印出来,方便我们找问题~
dio 网络请求工具代码
dart
import 'package:dio/dio.dart';
class AuthService {
final Dio _dio = Dio();
final String baseUrl = 'https://api.example.com';
AuthService() {
_dio.options.baseUrl = baseUrl;
_dio.options.connectTimeout = const Duration(seconds: 10);
_dio.options.receiveTimeout = const Duration(seconds: 10);
_dio.interceptors.add(LogInterceptor(requestBody: true, responseBody: true));
}
Future<Map<String, dynamic>> login(String username, String password) async {
if (username.isEmpty || password.isEmpty) {
return {'success': false, 'message': '用户名和密码都要填哦~'};
}
try {
final res = await _dio.post('/auth/login', data: {'username': username, 'password': password});
return {'success': true, 'data': res.data, 'message': '登录成功啦!'};
} on DioException catch (e) {
return {'success': false, 'message': e.response?.data['message'] ?? '网络不太好,再试一下吧~'};
}
}
}
四、第三步:用 Bloc 当 “状态小管家”🧸
登录之后,App 得知道我们是不是已经登录成功啦,不然打开别的页面,它都不知道我们是谁~这时候 Bloc 就像个贴心的小管家,帮我们管着登录状态呢!
Bloc 的工作流程超可爱的:用户点下登录按钮,Bloc 会收到一个 “登录请求” 的小事件,它会告诉 UI “我正在帮你登录哦”,等后端回复消息,再告诉 UI 成功还是失败~
Bloc 状态管理完整代码
dart
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'auth_service.dart';
// 事件
abstract class AuthEvent extends Equatable {
const AuthEvent();
}
class LoginSubmitted extends AuthEvent {
final String username;
final String password;
const LoginSubmitted({required this.username, required this.password});
List<Object> get props => [username, password];
}
// 状态
abstract class AuthState extends Equatable {
const AuthState();
}
class AuthInitial extends AuthState {
List<Object> get props => [];
}
class AuthLoading extends AuthState {
List<Object> get props => [];
}
class AuthSuccess extends AuthState {
final Map<String, dynamic> userInfo;
const AuthSuccess(this.userInfo);
List<Object> get props => [userInfo];
}
class AuthFailure extends AuthState {
final String errorMessage;
const AuthFailure(this.errorMessage);
List<Object> get props => [errorMessage];
}
// Bloc核心
class AuthBloc extends Bloc<AuthEvent, AuthState> {
final AuthService _service = AuthService();
AuthBloc() : super(AuthInitial()) {
on<LoginSubmitted>(_onLogin);
}
Future<void> _onLogin(LoginSubmitted event, Emitter<AuthState> emit) async {
emit(AuthLoading());
final result = await _service.login(event.username, event.password);
if (result['success']) {
emit(AuthSuccess(result['data']));
} else {
emit(AuthFailure(result['message']));
}
}
}
五、pubspec.yaml 依赖配置
yaml
dependencies:
flutter:
sdk: flutter
flutter_bloc: ^8.1.3
equatable: ^2.0.5
dio: ^5.4.0
这是我的运行截图:
六、跑起来啦!看看效果怎么样?✨
把页面、请求和状态管家拼在一起,整个登录流程就跑起来啦!我在鸿蒙真机上试了好几次,过程超顺利:
输入正确的用户名和密码,按钮变成小圈圈转了两圈,就跳转到主页面啦
输错密码的时候,页面会弹出小提示,告诉我们哪里错了
断网的时候,App 会温柔地提醒我们 “网络好像不太好,检查一下再试试吧”
把 App 退到后台再打开,它还记得我是登录状态,不用重新输入信息
看着自己做的小功能在鸿蒙设备上乖乖跑起来,真的超有成就感!原来给 App 做登录认证,也可以这么简单又可爱~
七、最后想说的话💌
这次用 Flutter 给鸿蒙 App 做登录认证,就像搭了一个小小的安全城堡,页面是软软的城门,请求是递进去的身份纸条,Bloc 是守着城门的小管家,每一步都稳稳的。
其实 Flutter 和鸿蒙的适配比我想象中要友好很多,只要注意好权限配置、页面适配和状态管理,就能做出又好用又可爱的功能啦~如果你也想给自己的鸿蒙 App 加个登录功能,不妨试试这个小方法,说不定会有意外的小惊喜哦!
更多推荐


所有评论(0)