7.2 读取用户资料&缓存
实现步骤:
第 1 步:常量定义
lib/common/values/constants.dart
1 2 3 4 5 6
| class Constants { ... static const storageToken = 'token'; static const storageProfile = 'profile'; }
|
storageToken 登录成功后 token
storageProfile 用户资料缓存
第 2 步:登录请求 model
lib/common/models/woo/request/user_login.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class UserLoginReq { String? username; String? password;
UserLoginReq({ this.username, this.password, });
factory UserLoginReq.fromJson(Map<String, dynamic> json) { return UserLoginReq( username: json['username'] as String?, password: json['password'] as String?, ); }
Map<String, dynamic> toJson() => { 'username': username, 'password': password, }; }
|
第 3 步:登录 token 模型
lib/common/models/user_token.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class UserTokenModel { String? token;
UserTokenModel({ this.token, });
factory UserTokenModel.fromJson(Map<String, dynamic> json) { return UserTokenModel( token: json['token'] as String?, ); }
Map<String, dynamic> toJson() => { 'token': token, }; }
|
第 4 步:用户资料 model
直接复制返回 json
生成model
类 lib/common/models/woo/user_profile_model
用不同的目录进行区分, request
response
的模型
第 5 步:api 编写
lib/common/api/user.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class UserApi { ...
static Future<UserTokenModel> login(UserLoginReq? req) async { var res = await WPHttpService.to.post( '/users/login', data: req, ); return UserTokenModel.fromJson(res.data); }
static Future<UserProfileModel> profile() async { var res = await WPHttpService.to.get( '/users/me', ); return UserProfileModel.fromJson(res.data); } }
|
第 6 步:用户服务类
lib/common/services/user.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| import 'dart:convert'; import 'package:get/get.dart';
import '../index.dart';
class UserService extends GetxService { static UserService get to => Get.find();
final _isLogin = false.obs; String token = ''; final _profile = UserProfileModel().obs;
bool get isLogin => _isLogin.value;
UserProfileModel get profile => _profile.value;
bool get hasToken => token.isNotEmpty;
@override void onInit() { super.onInit(); token = Storage().getString(Constants.storageToken); var profileOffline = Storage().getString(Constants.storageProfile); if (profileOffline.isNotEmpty) { _profile(UserProfileModel.fromJson(jsonDecode(profileOffline))); } }
Future<void> setToken(String value) async { await Storage().setString(Constants.storageToken, value); token = value; }
Future<void> getProfile() async { if (token.isEmpty) return; UserProfileModel result = await UserApi.profile(); _profile(result); _isLogin.value = true; Storage().setString(Constants.storageProfile, jsonEncode(result)); }
Future<void> setProfile(UserProfileModel profile) async { if (token.isEmpty) return; _isLogin.value = true; _profile(profile); Storage().setString(Constants.storageProfile, jsonEncode(profile)); }
Future<void> logout() async { await Storage().remove(Constants.storageToken); _profile(UserProfileModel()); _isLogin.value = false; token = ''; }
Future<bool> checkIsLogin() async { if (_isLogin.value == false) { await Get.toNamed(RouteNames.systemLogin); return false; } return true; } }
|
第 7 步:注册 UserService 服务
lib/global.dart
1
| Get.put<UserService>(UserService());
|
第 8 步:登录请求
lib/pages/system/login/controller.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| Future<void> onSignIn() async { if ((formKey.currentState as FormState).validate()) { try { Loading.show();
UserTokenModel res = await UserApi.login(UserLoginReq( username: userNameController.text, password: passwordController.text, ));
await UserService.to.setToken(res.token!); await UserService.to.getProfile();
Loading.success(); Get.back(result: true); } finally { Loading.dismiss(); } } }
|
第 9 步:HTTP 头加入 token 认证
lib/common/services/wp_http.dart
1 2 3 4 5 6 7 8 9 10 11 12 13
| class RequestInterceptors extends Interceptor { @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
if (UserService.to.hasToken) { options.headers['Authorization'] = 'Bearer ${UserService.to.token}'; }
return handler.next(options); }
|
第 10 步:401 错误处理
lib/common/services/wp_http.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| Future<void> _errorNoAuthLogout() async { await UserService.to.logout(); Get.offAndToNamed(RouteNames.systemLogin); }
@override Future<void> onError(DioError err, ErrorInterceptorHandler handler) async { final exception = HttpException(err.message); switch (err.type) { case DioErrorType.response: { final response = err.response; final errorMessage = ErrorMessage.fromJson(response?.data); switch (errorMessage.statusCode) { case 401: _errorNoAuthLogout(); break; ...
|
提交代码到 git