前言
在以flutter為底的app專案中,用戶登錄,退出等認證必須做在flutter專案里,那么采用何種狀態管理,來全域管理用戶認證呢?
今天我就借助flutter_bloc這個庫來搭建一套可以復用的成熟用戶認證系統
搭建前夕準備
一、我們需要了解現有app有多少認證事件,那么常規來說,流程如下:
1、啟動app,判斷有無token,有token則跳轉首頁獲取資料,無token則跳轉需要授權頁面如登錄頁
2、登錄頁登錄,登陸后保存token,跳轉首頁
3、退出登錄,洗掉token跳轉需要授權頁
那么總結起來就有三種事件
1、啟動事件
2、登錄事件
3、退出登錄事件
二、那么有了認證事件,我們還需要有幾個認證狀態,有哪些狀態呢,我來梳理一下:
1、在app啟動后,需要初始化用戶狀態,那么用戶當前是一個身份需要初始化的狀態
2、如果有token,或者用戶登錄后那么用戶就是一個已認證的狀態
3、如果用戶退出登錄,那么用戶當前是未認證的狀態
三、咱們還需要做一個用戶認證介面,介面主要是為了解耦,為了后期擴展能力、介面需要有哪些內容呢繼續梳理一下:
1、是否有token,token是決定app是否認證的關鍵
2、洗掉token,退出登錄需要洗掉
3、保存token,登錄需要保存
4、跳轉授權頁面
5、跳轉非授權頁面
準備好如上作業,那么我們開始搭建用戶認證系統吧
1、先撰寫認證事件:
part of 'authentication_bloc.dart';
//App認證事件,一般來說有三種,啟動認證,登錄認證,退出認證
abstract class AuthenticationEvent extends Equatable {
const AuthenticationEvent();
@override
List<Object?> get props => [];
}
//App啟動事件
class AppStart extends AuthenticationEvent{}
//App登錄事件
class LogIn extends AuthenticationEvent{
final String token;
LogIn(this.token);
@override
List<Object?> get props => [token];
@override
String toString() =>"LoggedIn { token: $token }";
}
//App退出事件
class LogOut extends AuthenticationEvent{}
2、撰寫認證狀態
part of 'authentication_bloc.dart';
/// 認證狀態
abstract class AuthenticationState extends Equatable {
const AuthenticationState();
@override
List<Object> get props => [];
}
/// - uninitialized - 身份驗證未初始化
class AuthenticationUninitialized extends AuthenticationState {}
/// - authenticated - 認證成功
class AuthenticationAuthenticated extends AuthenticationState {}
/// - unauthenticated - 未認證
class AuthenticationUnauthenticated extends AuthenticationState {}
3、撰寫外部介面
abstract class IUserAuthentication{
bool hasToken();
void saveToken(String token);
void deleteToken();
void authPage();
void unAuthPage();
}
4、有了如上的內容咱們就可以撰寫核心邏輯bloc了
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'i_user_authentication.dart';
part 'authentication_event.dart';
part 'authentication_state.dart';
class AuthenticationBloc extends Bloc<AuthenticationEvent, AuthenticationState> {
final IUserAuthentication iUserAuthentication;
/// 初始化認證是未認證狀態
AuthenticationBloc(this.iUserAuthentication) : super(AuthenticationUninitialized());
@override
Stream<AuthenticationState> mapEventToState(
AuthenticationEvent event,
) async* {
if(event is AppStart){
// 判斷是否有Token
if(iUserAuthentication.hasToken()){
yield AuthenticationAuthenticated();
} else {
yield AuthenticationUnauthenticated();
}
}else if(event is LogIn){
iUserAuthentication.saveToken(event.token);
yield AuthenticationAuthenticated();
}else if(event is LogOut){
iUserAuthentication.deleteToken();
yield AuthenticationUnauthenticated();
}
}
}
為了使用方便咱們需要做一個工具類來支撐外部使用
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'authentication_bloc.dart';
class Authentication{
static TransitionBuilder init({
TransitionBuilder? builder,
}) {
return (BuildContext context, Widget? child) {
var widget = BlocListener<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
var bloc = BlocProvider.of<AuthenticationBloc>(context);
if (state is AuthenticationAuthenticated) {
bloc.iUserAuthentication.authPage();
} else if (state is AuthenticationUnauthenticated) {
bloc.iUserAuthentication.unAuthPage();
}
},
child: child,
);
if (builder != null) {
return builder(context, widget );
} else {
return widget;
}
};
}
}
使用
在專案中如何使用呢??
1、介面事件類
2、bloc初始化
3、監聽初始化
代碼如下:
介面實作類
class Auth implements IUserAuthentication{
static final String userTokenN = 'userToken';
Auth(){
_userMMKV = MMKVStore.appMMKV(name: "123");
}
@override
void authPage() {
RouterName.navigateTo(LibRouteNavigatorObserver.instance.navigator!.context, RouterName.home,clearStack: true);
}
late MMKV _userMMKV;
@override
void deleteToken() {
_userMMKV.removeValue(userTokenN);
}
@override
bool hasToken() {
return _userMMKV.decodeString(userTokenN)!=null;
}
@override
void saveToken(String token) {
_userMMKV.encodeString(userTokenN, token);
}
@override
void unAuthPage() {
RouterName.navigateTo(LibRouteNavigatorObserver.instance.navigator!.context, RouterName.login,replace: true);
}
}
2、初始化
MultiBlocProvider(
providers: [
//AuthenticationBloc bloc初始化
BlocProvider(create: (_) => AuthenticationBloc(Auth())),
],
child: MaterialApp(
...
builder: Authentication.init() //監聽初始化
),
);
3、事件呼叫
1、退出按鈕呼叫,BlocProvider.of(context).add(LogOut())
2、登錄頁面呼叫,BlocProvider.of(context).add(LogIn(“123”))
3、SplashPage頁面呼叫 BlocProvider.of(context).add(AppStart())
大功告成
如上搭建的一個用戶認證系統,可以抽離專案做成package,再下次開發其他專案時候,就可以直接使用,方便快捷,
更多flutter教程請關注我的IMGeek:https://www.imgeek.org/people/33692
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/384308.html
標籤:其他
