在不使用 Firebase 的情况下使用电子邮件和密码进行 Flutter 身份验证

Flutter authentication with email and password without using Firebase

是否可以在不使用 firebase 的情况下通过电子邮件和密码在 flutter 中实现身份验证?我一般搜索了 Whosebug 和互联网,但一无所获。 我正在创建一个简单的身份验证 class 这是我目前所做的:

class User {
  bool isAuthenticated = false;
  late String userid;
  late String username;
  late String email;
  late DateTime expireDate; // this variable is used to make the user re-authenticate when today is expireDate

  User(bool isAuthenticated, String userid, String username, String email) {
    this.isAuthenticated = isAuthenticated;
    this.userid = userid;
    this.username = username;
    this.email = email;
    this.expireDate = new DateTime.now().add(new Duration(days: 30));
  }
}

class Authentication {
  Future<User> signin(String email, String password) {}

  void signup(String username, String email, String password) {}
}

编辑 #1:我知道如何设置基于 cookie/token 的身份验证服务器 我有自己关于该主题的回购协议:cookie authentication, token authentication 但我不知道如何处理 tokens/cookies在颤抖。

是的,完全可以在没有 Firebase 的情况下创建身份验证,但它变得更加困难并且有多种解决方案。

firebase 提供的内容:

  1. 服务器space没有停机时间
  2. 完整的 Api 集,包括各种方法的身份验证
  3. 强大的安全性(由 google 构建)
  4. 易于使用和设置,文档丰富

我提出这些的原因是因为你寻找的替代方案对于一个相对较新的程序员来说非常困难,并且感觉你正在一次构建多个应用程序。这绝对是一个学习曲线。另外我假设你不只是想要本地身份验证因为那有点毫无意义。

创建您自己的后端涉及:

  1. 设置服务器(通常 ubuntu)(在 raspi 或像亚马逊、数字海洋等主机上)
  2. 使用表设置数据库(mysql, sql, mongoDB)
  3. 正在创建通信 API 的(php、Node.js)

这就是我推荐的后端开发人员, 使用 LAMP 架构:Linux、Apache、MySQL、PHP

设置 Lamp 并不难,这里是 link 我关注的是:

https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-16-04

设置后端后,您必须从 flutter 创建 api 调用。 调用(如果你创建了一个人们可以登录的 auth.php)看起来像:

http://ip:8080/auth.php?email="example@gmail.com"&pass="123456"

我理解为什么您觉得没有找到解决方案,我也遇到过,但是有很多,LAMP 是比较容易的解决方案之一。如果您仍然感兴趣,我建议您查看系统设计课程。

您可以使用 Nodejs 和 express 创建您自己的 API 和 MongoDB 或任何其他数据库作为持久数据库。我附上了我的 github 仓库 link,它具有在 mongodb

中设置 email/password 身份验证所需的最少代码

Github 编辑:

我对会话几乎一无所知,但对于令牌,pub.dev 中有包可以让您解码令牌。 jwt-decoder。 您可以使用此包检查令牌的到期时间,并可以使用 secure_storage

来存储它们

我查看了您的令牌身份验证存储库。我建议您在获得令牌时验证它们,而不是盲目相信它们。

此答案基于#edit1。由于您提到您已经知道如何在服务器端设置令牌,所以您已经完成了一半。这是我所做的一些假设,您已经知道 js/php 并使用 JSON 输出,数据库已经有一个列和 table 用于跟踪会话和 user_id .

既然您知道 Cookie 是如何构建的,那么这应该相对容易,因为我是围绕类似的体系结构构建的。我们必须使用应用程序提供访问权限的本地内存。 flutter 中有两个包允许你这样做,你可以使用:

主要区别在于,如果您想存储 'tokens' 或您希望安全的数据,您显然会使用 flutter_secure_storage。我将使用它作为代码示例。是的,即使在应用程序关闭后数据也会保存。

设置令牌(flutter):

  1. 设置用户Class

当使用 firebase 时,我们通常认为 flutter_auth 附带的用户 class 是理所当然的,但这基本上是我们必须构建的。一个用户 class 拥有你想要存储的所有数据,然后是一个名为 authenticate 的函数。

 class AppUser{
     final _storage = new FlutterSecureStorage();
     //below class is mentioned in the next part 
     AuthApi api = new AuthApi();

     //constructor 
     AppUser(){
         //ur data; 
     }; 

     Future<bool> authenticate(email, password) async {
         //this is the api mentioned in next part 
         http.Response res = await api.login(email, password);
         Map<String, dynamic> jsonRes = jsonDecode(res.body);

         if (jsonRes["error"]) {
              return false;
         }
         _setToken(jsonRes["token"]);
         _setUID(jsonRes["user-id"].toString());
         _setAuthState(true); 
         return true; 
     }

     Future<void> _setToken(String val) async {
         //how to write to safe_storage 
         await _storage.write(key: 'token', value: val);
     }
     Future<void> _setUID(String val) async {
         await _storage.write(key: 'user_id', value: val);
     }

      //you can stream this or use it in a wrapper to help navigate 
      Future<bool> isAuthenticated() async {
         bool authState = await _getAuthState();
         return authState;
      }

      Future<void> _getAuthState() async {
         //how to read from safe_storage u can use the same to read token later just replace 'state' with 'token'
         String myState = (await _storage.read(key: 'state')).toString();
         //returns boolean true or false 
         return myState.toLowerCase() == 'true';
      } 

      Future<void> _setAuthState(bool liveAuthState) async {
         await _storage.write(key: 'state', value: liveAuthState.toString());
      }

 }

假设你要在按下按钮时进行身份验证,所以它看起来像

onPressed(){
        AuthUser user = new AuthUser(); 
        if(user.authenticate(email, password)){
            //if logged in. Prolly call Navigator.
        }else{
            //handle error
        }
}
  1. 正在设置 api 个电话

好的,所以这是在调用 Node express API,json 输出看起来像

//if successful 
{"status":200, "error": false, "token": "sha256token", "user-id": "uid"}

我们需要创建一个 class,它将为我们提供进行此调用的输出,因此 AuthApi class

class AuthApi {
   //this is the login api and it returns the above JSON 
   Future<http.Response> login(String email, String password){
        return http.post(
           Uri.parse(ip + '/api/auth/login'),
           headers: <String, String>{
           'Content-Type': 'application/json',
           },
           body: jsonEncode(<String, String>{
           "email": email,
           "password": password,
           }),
       );
  }
}

感谢您澄清您的需求,这有助于更好地回答。