路由過濾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頁面。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM