• 路由过滤token,验证过期,添加白名单


    题外话:将后端文件通过功能进行分类有利于代码的维护。这里目录结构是:直属index.js文件统一处理各个文件与外部的交互。

    后端在验证token的时候,需要用到一个库express-jwt,用来验证token、token是否过期和添加不需要验证身份即可访问的路由接口白名单。

    这里用到的是盐值加密方法。

    jwt配置

    const expressAuth = expressJwt({
      secret: PRIVATE_KEY,
      //PRIVATE_KEY:盐值,在后端指定的常量,参与身份加密,解密的时候同样需要验证解密出的盐值是否与原值匹配
      credentialsRequired: true,
      algorithms: ['HS256']//这里必须添加algorithms,指定给token加密的算法
    }).unless({
      path: ['/','/user/login']//不需要验证token的路由白名单
    })
    

      

    在统一处理路由的文件(index.js)中添加express-jwt的验证并挂载到路由:

    const expressAuth=require("./jwt")
    
    const router=express.Router()
    //紧接着写express-jwt的token验证方法:
    router.use(epressAuth)

    生成和解密token;

    //封装生成token的方法
    let jwt = require("jsonwebtoken")
    //加密解密
    let Token = {
      //生成token
      encrypt(data) {
        return jwt.sign(data,'token',{expiresIn: 60 * 60 * 24})
      },
      //token解密明了版本
      decrypt(token) {
        try {
          let data = jwt.verify(token,'token')
          return {
            token: true,
            id: data.uid,
            uname: data.uname,
            role: data.role,
            avatar: data.avatar
          }
        } catch (e) {
          return {
            token: false,
            data: e
          }
        }
      },
      //token解密封装版本,从请求头中获取token并解密
    
      decode(req) {
    
        const authorization = req.headers.authorization
        let token = ''
        if (authorization.indexOf('Bearer') >= 0) {
          token = authorization.replace("Bearer ","")
        } else {
          token = authorization
        }
        // console.log(token)
        return jwt.verify(token,PRIVATE_KEY,{algorithms: 'HS256'})
      }
    }
    

      

      这里用到错误处理插件为boom,处理错误的方法:

    //这里需要创建一个规范响应的构造函数Result,定义处理其中成功的请求:success方法;失败的请求:fail方法;token过期的方法:expired方法
    //集中处理404请求的中间件,必须放在正常处理流程之后
    router.use((req,res,next) => {
      next(boom.notFound("接口不存在"))
    })
    
    //boom中间件会在遇到异常的时候把异常信息传递给异常处理中间件
    //所以接下来要写异常处理中间件
    router.use((err,req,res,next) => {
      if (err.name && err.name === 'UnauthorizedError') {
        const {status = 401,message} = err
        new Result(null,'Token失效',{
          error: status,
          errMsg: message
        }).expired(res.status(status))
      } else {
        const msg = (err && err.message) || '系统错误'
        const statusCode = (err.output && err.output.statusCode) || 500;
        const errorMsg = (err.output && err.output.payload && err.output.payload.error) || err.message
        new Result(null,msg,{
          error: statusCode,
          errorMsg
        }).fail(res.status(statusCode))
      }
    })
    

      

    小贴士:如果不添加加密的方法,这里的expried添加的信息将不会在返回响应的信息中。

    在添加了算法HS256后,在解析token的时候需要使用同样算法的解密:jtw.verify(token,PRIVATE_KEY,HS256')。

    用户验证身份的过程:用户在发送请求的时候是将前端用以登录的用户信息发送给后端,后端用以加密后返回给前端,然后前端使用添加了token信息的请求头向后端发送请求,后端从请求头中拿出token,使用解密方法解密,以下decode方法返回的是Boolean类型,可以用来反应用户身份是否正确。

    在没有添加加密和解密的时候虽然依然可以通过getInfo获取到用户的信息,但是用户白名单和过期token的检测会出现问题,具体表现在:进入登陆页面的时候直接报错为token过期的错误提示,并强行跳回login页面。

  • 相关阅读:
    inflate用一个XML源填充view. LayoutInflater
    关于inflate的第3个参数
    关于inflate的第3个参数
    android ImageView scaleType属性
    android ImageView scaleType属性
    Android中设置文本颜色的三种方法
    JDK1.8与spring3.x的不兼容
    Spring整合activiti单元测试
    良好编程习惯的养成
    No output operations registered, so nothing to execute
  • 原文地址:https://www.cnblogs.com/qingsui/p/13509766.html
Copyright © 2020-2023  润新知