美文网首页
“真实世界”全栈开发-3.5-验证令牌的中间件

“真实世界”全栈开发-3.5-验证令牌的中间件

作者: 桥头堡2015 | 来源:发表于2018-02-06 10:08 被阅读26次

    上一讲利用Passport实现了发放令牌的中间件,这一讲来实现验证令牌的中间件。

    前面说到,端点根据需不需要验证信息可以分为三类:不需要,需要和可有可无。

    第一类不需要验证。

    第二类必需验证信息,比如用户发表新的博文时,必须把后端签发的令牌同添加博文的请求一起传给后端。

    第三类端点,比如返回某个标签下的所有博文列表,请求里可以不带令牌,但是如果有合法的令牌的话,就返回与用户身份相关的额外信息,比如该用户是否为列表里的博文点过赞。对应第二三类端点,得有两套不同的逻辑块来负责验证用户身份:必需验证信息的和可以不用验证信息的,即是说,我们这一讲要实现的其实是两个不同的中间件。

    新建文件routes/auth.js,先导入所需的依赖:

    const secret = require('../config').secret;
    const jwt = require('express-jwt');
    

    验证令牌需要用到签发令牌的同一口令,所以从config/index.js中导入secret。重复一遍,在开发环境,secret的值是写在文件中的,而在生产环境,它的值是从环境变量中读取的。

    具体到验证令牌中间件的代码实现,我们会用到express-jwt这个包(没错,安装过了)。这个包可以很方便地按照传入的参数,生成Express中间件。这里可以查阅它所接受的所有配置选项。

    继续写入如下的代码:

    const jwt = require('express-jwt');
    const secret = require('../config').secret;
    
    // +++
    function getTokenFromHeader(req) {
      var authHeader = req.header('authorization');
      if (!authHeader) return null;
      const [name, token] = authHeader.split(' ');
      if (name === 'Token' && token)
        return token;
      return null;
    }
    
    const auth = {
      required: jwt({
        secret,
        userProperty: 'payload',
        getToken: getTokenFromHeader
      }),
      optional: jwt({
        secret,
        userProperty: 'payload',
        credentialsRequired: false,
        getToken: getTokenFromHeader
      })
    };
    // +++
    

    其中getTokenFromHeader是一个辅助函数。从名字可以看出来,我们用它从请求头中抽取JWT令牌。它检查Authorization这个请求头(req.header不区分大小写),返回所带的令牌或者null

    接下来我们定义了两个中间件requiredoptional。它们都是由express-jwt自动生成的。我们给optional传入了credentialsRequired: false这条配置,表示就算没有令牌,验证也会成功。userProperty: payload则表示令牌的信息会存储在req.payload里面(req是代表中间件所接受的代表请求的参数)。

    最后,我们需要把上面定义的中间件暴露给后端应用的其它文件。在routes/auth.js的最后加入:

    module.exports = auth;
    

    到此,验证用户身份的中间件都定义好了。接下来要做的就是把这些中间件整合到整个Express应用的中间件栈(也就是逻辑链条)中去。

    相关文章

      网友评论

          本文标题:“真实世界”全栈开发-3.5-验证令牌的中间件

          本文链接:https://www.haomeiwen.com/subject/jkomzxtx.html