繁体   English   中英

如何在flutter中存储cookie并使用它来验证用户是否登录

[英]How to store Cookies in flutter and use it to authenticate if user is logged in or not

我正在尝试创建一个平台,一旦我登录它,就会创建一个令牌并将其存储在 cookie 中。 我已经成功地创建了一个使用节点 js 存储 cookie 的路由(我可以看到它保存在邮递员中)。 但是一旦我尝试在我的颤振应用程序中使用该路线,似乎令牌不会保存在任何地方。

如何保存 cookie 并使用它来验证用户是否应该登录或应该再次登录

登录.dart

Future<void> _signIn(email, password) async {
    try {
      setState(() {
        LoadingWidget.show(context);
        bool _absorbme = true;
      });

      var url = "http://192.168.8.23:3000/route/login"; // iOS
      final http.Response response = await http.post(
        Uri.parse(url),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: jsonEncode(<String, String>{
          'email': email.toLowerCase(),
          'password': password,
        }),
      );

      SharedPreferences prefs = await SharedPreferences.getInstance();
      var parse = jsonDecode(response.body);
      await prefs.setString('msg', parse["msg"]);
      await prefs.setString('success', parse["success"]);
      String? msg = prefs.getString("msg");

    } finally {
      setState(() {
        LoadingWidget.hide(context);
        bool _absorbme = false;
      });
    }
  }

我的 Route.js 文件

const express = require('express');
const router = express.Router();
const Users = require('./model/model')
const passport = require('passport')
const bcrypt = require("bcrypt");
const { createTokens, validateToken, authenticateToken } = require("./JWT");
const Server = require('http-proxy');
router.get('/', (req, res)=>{
  res.send('Hello world')
})

router.post("/signup", async (req, res) =>  {

  const { username, email, password } = req.body;
  let user = await Users.findOne({ email });

  if (user){ 
    
    return res.status(400).json({success: 'false', msg: "Email Already Exist"});
  }
  bcrypt.hash(password, 10).then((hash) => {
    Users.create({
      username: username,
      password: hash,
      email:email,
    })
      .then(() => {
        res.json({success: 'true', msg: 'login Successfully'});
      })
      .catch((err) => {
        if (err) {
          res.status(400).json({success: 'false', msg: 'Failed to save'});
        }
      });
  });
});

router.post("/login", async (req, res) => {
  const { email, password } = req.body;

  let user = await Users.findOne({ email });

  if (!user) {
    
    return res.status(400).json({success: 'false', msg: 'Authentication Failed, User not found'});
  }

  const dbPassword = user.password;
  bcrypt.compare(password, dbPassword).then((match) => {
    if (!match) {
      res
        .status(400)
        .json({success: 'false',  msg: 'Authentication failed, wrong password'});
    } else {
      const accessToken = createTokens(user);

      var token = res.cookie("access-token", accessToken, {
        maxAge: 60 * 60 * 24 * 30 * 1000,
        httpOnly: true,
      });
      
      res
        .status(200)
        .json({success: 'true',  msg: 'Successfully logged In'});
    }
  });
});

router.get("/profile", validateToken, async (req, res) => {
 let user = await Users.findOne({email: req.decoded.email});
 return res.json({
   email: user.email, 
   balance: user.balance,
   name: user.username
})


router.get("/logout", validateToken, (req, res) => {
  return res
    .clearCookie("access-token")
    .status(200)
    .json({success: "true" , msg: "Successfully logged out" });
});

router.get("/authenticate" ,authenticateToken, (req,res)=>{

})


  module.exports = router;

在此处输入图像描述

为什么不使用 JWT 它可以帮助您在指定的小时数内管理用户

在您的 api 上创建授权端点以在过期时刷新令牌。 在 dart 端,创建一个经过身份验证的客户端单例。

class AuthenticatedClient extends http.BaseClient {
  factory AuthenticatedClient() => _instance;
  AuthenticatedClient._();

  static final _instance = AuthenticatedClient._();

  int? expiresAt;
  String? token;
  final _client = http.Client();

  void setParams(http.Response res) {
    final response = jsonDecode(res.body);

    expiresAt = response['expiresAt'];
    token = response['token'];
  }

  Future<void> authorize() async {
    // Send a request to refresh token, update token and expiresAt
    // accordingly. Note that, you can't use _client to send request, use 
    // htt.put, http.post.
    // Ex:
    //
    // final response = await http.put(
    //  Uri.parse('https://myapi.com/authorize'),
    //  headers: {
    //    'Content-Type': 'application/json',
    //  },
    //  body: jsonEncode({
    //    'email': <email>,
    //    'password': <password>,
    //  }),
    // );
    //
    // setParams(response);
  }

  @override
  Future<http.StreamedResponse> send(http.BaseRequest request) async {
    // Ensure you set params for the first time.
    assert(expiresAt != null);

    if (expiresAt! < DateTime.now().millisecondsSinceEpoch) {
      await authorize();
    }

    request.headers['Authorization'] = 'Bearer $token';

    return _client.send(request);
  }
}

在您的 api 上,在loginsignup请求上生成一个令牌并将令牌发送给客户端。 对于此示例,响应格式为:

{
  'token': <generated token>,
  'expiresAt': <timestamp>,
}

收到响应后,调用AuthenticatedClientsetParams方法并设置请求参数。 我没有在示例中添加错误处理代码,不要忘记添加。

像这样使用AuthenticatedClient

AuthenticatedClient().get(Uri.parse('https://myapi/profile'));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM