意思是:通过 JWT 登录

Posted

技术标签:

【中文标题】意思是:通过 JWT 登录【英文标题】:MEAN: Loggin in by JWT 【发布时间】:2016-08-08 23:51:03 【问题描述】:

[Q1] 当我可以通过检查req.cookies 对象? (在后端 NodeJS)

我正在尝试了解 JSON 网络令牌的功能。我设置的演示应用程序具有登录功能。

    在 GET '/login' 上,我可以生成一个令牌,用它设置一个 cookie。 在前端,我可以访问包含令牌的 JSON 对象。 我可以在开发者控制台中查看 cookie。

Nodejs:

index.js - 登录路径

router.post('/login', function(req, res, next) 
  Authenticator.find(req.cookies.token, req.body, Heartbeat.common, function(err, warning, data)
    if(err) 
      res.status(404).send(token:false, warning: null, error:err);
     else if(warning)
      res.status(200).send(token:true, warning: warning, error:null);
     else 
      res.cookie('token', data, maxAge: 3600000, httpOnly:true);
      res.status(200).json(token:true, error: null);
    
  );
);

Authenticator.ctrl.js - Authenticator.find()

find: function(token, user, heartbeat, callback) 
  if(!token) 
    Auth.findOne(email:user.email, function(err, data)
      if(err) 
        console.log(err);
       else 
        if(data) 
          if(data.checkHash(user.password)) 
            callback(null, null,TokenMaker.createToken(user.email, heartbeat));
           else 
            callback(Errors.login.strict.MISMATCH, null, null);
          
         else 
          callback(Errors.login.strict.NOT_REGISTERED, null, null);
        
      
    );
   else 
    callback(null, Errors.login.warning.ACTIVE_REFRESH, null);
  
,

角度控制器

app.controller('userAccessCtrl', ['$scope', '$http', function ($scope, $http)
  $scope.user = 
    email: "someone@some.com",
    password: "12345679"
  ;
  $scope.error = ;
  $scope.loginAccess = function(user) 
    var submitReady = true;
    var emailStatus = EmailValidator.email(user.email);
    var passwordStatus = EmailValidator.password(user.password);
    if(typeof emailStatus === "string") 
      $scope.error.email = emailStatus;
      submitReady = false;
    
    if(typeof passwordStatus === "string") 
      $scope.error.password = passwordStatus;
      submitReady = false;
    
    if(submitReady) 
      $scope.error = 
      var data = $scope.user;
      $scope.user = ;
      $http.post('/login', data)
        .then(function(success)
            console.log(success);
          ,function(error)
            console.log(error);
        );
    


]);

控制台响应:


  "data": 
    "token":true,
    "error":null
  ,
  "status":200,
  "config":
    "method":"POST",
    "transformRequest":[null],
    "transformResponse":[null],
    "url":"/login",
    "data":
      "email":"someone@some.com",
      "password":"12345679"
    ,
    "headers":
      "Accept":"application/json, text/plain, */*",
      "Content-Type":"application/json;charset=utf-8"
    
  ,
  "statusText":"OK"

【问题讨论】:

拦截器的一些代码怎么样?此外,您通常会发现人们使用本地和会话存储而不是 cookie。理想情况下,您将在成功调用后端的身份验证后存储令牌,拦截器只需从中获取值并为每个请求构建标头。使用 cookie 与存储取决于您的令牌是如何设置的,它是否包括到期日期以及许多其他因素。阅读差异。 @Vaelyr 我提到了这个 SO 问题link。我正在设置 cookie 和令牌的到期时间。我对拦截器的使用感到好奇,因为每个连续的请求无论如何都会在 cookie 中包含令牌(如果存储 JWT 不会对服务器造成任何负担) 据我了解,您的第二个问题是您无法使 cookie 正常工作吗?无论您选择哪种解决方案,您都必须通过标头或 cookie 将其传递给后端进行验证。它是无状态机制,因此与服务器负担相反 - 没有会话。您可以显示创建标头的代码吗? @Vaelyr 我已经添加了代码。开发者控制台显示创建的令牌,但我在成功对象中看不到它 所以我仍然没有看到任何角度拦截器。您需要有一个拦截器,它将初始身份验证令牌(我假设您存储为 cookie)放回响应中,例如使用 $cookies 【参考方案1】:

其实使用 cookie 和 JWT 令牌是错误的。 JWT 令牌在身份验证方面比 cookie 好得多。 当您使用令牌时,您的服务器不需要将会话存储在内存数据库中,这对您的应用程序来说是一个很大的优势 - 您可以扩展您的应用程序,添加新服务器,而无需考虑如何在服务器之间同步会话。

简而言之,当您使用 JWT 令牌时,您的流程就是下一个:

前端(在你的情况下它是一个角度)将登录名和密码发送到 /login 路由 后端检查凭据并发回令牌(在请求正文中,而不是在 cookie 中) 前端应用将令牌保存在浏览器的本地存储或会话存储中

您可以编写 HTTP 拦截器,它将拦截所有对后端的请求,并将“授权”标头附加到所有请求,如下所示:

授权:Bearer here-is-your-jwt-token

后端可以检查此授权标头,如果正确(查看http://jwt.io 以了解验证的工作原理)后端可以为您提供请求。

【讨论】:

“其实使用cookie和JWT令牌是错误的。JWT令牌比cookie更适合认证”你能详细说明为什么吗?我已经阅读了有关 XSS 和 CSRF 攻击的信息,他们说通过保持 httpOnly true 将令牌存储在 cookie 中更安全,这样 js 就无法访问 cookie。 令牌经常与 API 一起使用,当某些服务器为移动、桌面或网站应用程序提供 API 时。令牌的主要优点是无状态 - 这意味着您的服务器不需要存储(在内存、Redis、数据库、文件......)令牌,服务器只需生成 JWT 令牌并将其返回给应用程序。这允许您简单地扩展您的应用程序,如果您的应用程序负载非常大,您的用户会向您的后端发出许多请求,验证所有请求的用户会话将比验证 JWT 令牌花费更长的时间。 当然,带有 HTTPonly 标志的会话 cookie 更安全且易于实现,但是如果您的后端需要处理来自不同主机的请求(如果您要创建移动或桌面应用程序),它将是最好使用 JWT 令牌,不要再使用 session。 我所做的只是 1. 创建一个令牌 2. res.cookie('token', data, maxAge: age); 我的 Angular 应用程序可以访问该令牌。我自己还没有设置任何会话,您能否指导我找到一个资源,该资源解释了在可以在标头中设置令牌时如何使用存储令牌? 也许本教程对你有帮助angular-tips.com/blog/2014/05/json-web-tokens-examples

以上是关于意思是:通过 JWT 登录的主要内容,如果未能解决你的问题,请参考以下文章

记webman 构造函数__construct 里request问题 通过中间件 使用jwt验证用户登录状态

单点登录JWT与Spring Security OAuth

从 Cognito 收到 JWT Token 后如何存储?通过 Cognito 托管 UI 登录

我可以通过 django-rest-auth 登录和注册返回 JSON Web Token (JWT) 吗?

总结关于spring security 使用 JWT 和 账户密码登录 整合在一起的新感悟

通过 Express / Auth0 后端登录用户