我是新手,需要帮助。 我正在构建一个多页应用程序,并使用名为Routes的导航来构建。 使用提供程序包进行身份验证状态管理。下面是我的代码。
class MainWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: Auth()),
],
child: Consumer<Auth>(
builder: (ctx, authData, child) =>
MaterialApp(
debugShowCheckedModeBanner: false,
title: "SupraFin",
theme: ThemeData(
primaryColor: Colors.blue,
accentColor: Colors.grey,
fontFamily: 'Overpass'),
home: authData.isAuthenticated
? Scaffold(body: Center(child: Text('inAuthenticated Flow'),),)
: FutureBuilder(
future: authData.tryAutoLogin(),
builder: (ctx, authDataSnapshot) {
if (authDataSnapshot.connectionState ==
ConnectionState.waiting) {
return LoadingScreen();
}
return SplashScreen();
}),
routes: MyRoutes.routes,
),
),
);
}
}
下面是MyRoutes类,我正在用它在单个文件中维护路由。
static const SPLASH_PAGE = '/';
static const LOGIN_PAGE = '/login';
static const SIGN_UP_PAGE = '/signup';
static const HOME_PAGE = '/home-page';
static const LOGIN_OTP_PAGE = '/login-otp-page';
static final routes = {
// SPLASH_PAGE: (_) => SplashScreen(),
LOGIN_PAGE: (_) => LoginPage(),
LOGIN_OTP_PAGE: (_) => ActivateOTPPage(),
// SIGN_UP_PAGE : (_) =>
HOME_PAGE: (_) => HomePage(),
};
}
下面是我的身份验证提供程序,在其余服务中,我只是发出http请求并抛出我在Widget上捕获的错误。 11:32
class Auth with ChangeNotifier {
String _token;
DateTime _expiryDate;
UserType _userType;
bool _isOTPVerified = false;
Timer _authTimer;
bool get isAuthenticated {
print(token != null && _isOTPVerified);
return token != null && _isOTPVerified;
}
String get token {
if (_expiryDate != null &&
_expiryDate.isAfter(DateTime.now()) &&
_token != null) {
return _token;
}
return null;
}
UserType get user{
return _userType;
}
Future<UserType> login(String email, String password) async {
RESTServices restServices = RESTServices();
var response = await restServices.post(
LOGIN_URL,
{'email': email, 'password': password},
);
if (response == null) {
return null;
}
var user = UserType.fromJson(response);
_token = user.accessToken;
_expiryDate = user.expiresAt;
_userType = user;
autoLogout();
notifyListeners();
var pref = await SharedPreferences.getInstance();
pref.setString('userData', json.encode(user.toJson()));
return user;
}
Future<bool> verifyOtp(String otp) async {
var restServices = RESTServices();
var response = await restServices.post(VERIFY_OTP_URL, {'otp': otp});
if (response == null) {
return false;
}
if (response['status'] != null && response['status'] == 'success') {
_isOTPVerified = true;
notifyListeners();
return true;
}
return false;
}
void logout() async{
print('Auth Provider: Logout');
_token = null;
_expiryDate = null;
_userType = null;
if(_authTimer != null){
_authTimer.cancel();
_authTimer = null;
}
notifyListeners();
var pref = await SharedPreferences.getInstance();
pref.remove('userData');
}
void autoLogout(){
print('Inside AutoLogOut');
if(_authTimer != null){
_authTimer.cancel();
_authTimer = null;
}
var timeLeftInSec = _expiryDate.difference(DateTime.now()).inSeconds;
_authTimer = Timer(Duration(seconds: 3), () => logout());
}
Future<bool> tryAutoLogin() async{
print('Inside Auto Login');
var pref = await SharedPreferences.getInstance();
if(!pref.containsKey('userData')){
print('Does Not contains key in pref');
return false;
}
var user = UserType.fromJson(json.decode(pref.getString('userData')));
if(user.expiresAt.isBefore(DateTime.now())){
print('Token is expired');
return false;
}
_token = user.accessToken;
_expiryDate = user.expiresAt;
_userType = user;
// notifyListeners();
autoLogout();
return true;
}
}
因此,登录后我将重定向到验证OTP屏幕,根据登录3秒后的代码,它应自动注销并在MaterialApp()上方通知消费者,这应再次检查authenticated是否为false,然后显示启动屏幕。但它仍在验证OTP页面上。我检查了isAuthenticated是否为假。 不明白是什么问题。
我还尝试了ChangeNotifierProvider(create:(ctx)=> Auth()),它仍然无法正常工作。
请帮助解决。 谢谢。