使用Firebase身份验证和Rest Api使用户永久登录Flutter

时间:2020-04-29 14:09:02

标签: firebase flutter restapi

我正在为我的应用程序使用Firebase电子邮件/密码身份验证,并使用共享首选项存储令牌。我想在令牌过期之前刷新令牌,以使用户在输入凭据后永久登录。这是我的代码

class Auth with ChangeNotifier{
  String _token;
  DateTime _expiryDate;
  String _userId;
  Timer _authTimer;

  bool get isAuth{
    return token!=null;

  }
  String get token{
    if(_expiryDate!=null&&_expiryDate.isAfter(DateTime.now())&& _token!=null){
      return _token; 
    }
    return null;
  }

  String get userId {
    return _userId;
  }


  Future<void> _authenticate(String email, String password, String urlSegment ) async {

    final url='https://identitytoolkit.googleapis.com/v1/$urlSegment? key';
    try{
      final response= await http.post(url, body: json.encode({
        'email': email,
        'password': password,
        'returnSecureToken': true,
      },
      ),
      );
      final responseData= json.decode(response.body);
      if(responseData['error']!=null){
        throw HttpException(responseData['error']['message']);
      }
      _token= responseData['idToken'];
      _userId=responseData['localId'];
      _expiryDate=DateTime.now().add(Duration
      (seconds: int.parse(
        responseData['expiresIn'])
        )
         );
         _autoLogout();
         notifyListeners();
         final prefs=await SharedPreferences.getInstance();
         final userData= json.encode({
           'token': _token,
           'userId': _userId,
           'expiryDate': _expiryDate.toIso8601String(),
         });
         prefs.setString('userData', userData);
    } catch (error){
      throw(error);
    }



  }


  Future<void> signup(String email, String password) async{
   return _authenticate(email, password, 'accounts:signUp');

  }

  Future<void> login(String email,String password) async{
  return _authenticate(email, password, 'accounts:signInWithPassword');
}
  Future<bool> tryAutoLogin() async{
    final prefs= await SharedPreferences.getInstance();
    if(!prefs.containsKey('userData')){
      return false;
    }
    final extractedUserData= json.decode(prefs.getString('userData')) as Map<String, Object>;
    final expiryDate= DateTime.parse(extractedUserData['expiryDate']);

    if(expiryDate.isBefore(DateTime.now()))
    {
      return false;
    }
    _token=extractedUserData['token'];
    _userId=extractedUserData['userId'];
    _expiryDate=expiryDate;
    notifyListeners();
    _autoLogout();
    return true;
  }

  Future<void>  logout() async{
    _token=null;
    _userId=null;
    _expiryDate=null;
    if(_authTimer!=null){
      _authTimer.cancel();
      _authTimer=null;
    }
    notifyListeners();
    final prefs= await SharedPreferences.getInstance();
    prefs.remove('userData');
  }

  void _autoLogout(){
    if(_authTimer!=null){
      _authTimer.cancel();
    }
    final timeToExpiry= _expiryDate.difference(DateTime.now()).inSeconds;
    _authTimer= Timer(Duration(seconds: timeToExpiry), logout);
  }
}

我想使用此方法,因为我在整个代码中都使用令牌进行身份验证。请提出任何实现刷新令牌的方法,以便即使在一个小时后也能保持登录状态。

0 个答案:

没有答案