JWT認(rèn)證機(jī)制

JWT認(rèn)證機(jī)制
session不可跨域,用戶信息保存在服務(wù)器端;
JWT可以跨域,用戶信息保存在瀏覽器;

JWT工作原理
1、客戶端通過瀏覽器輸入密碼用戶名發(fā)起登陸請(qǐng)求;
2、服務(wù)器驗(yàn)證后,對(duì)用戶信息通過加密后生成token字符串響應(yīng)給客戶端(服務(wù)器不保留token字符串);
3、將加密后token字符串存儲(chǔ)到local storage;
4、客戶端再次發(fā)起請(qǐng)求時(shí),會(huì)把token字符串發(fā)送給服務(wù)器端;
5、服務(wù)器端收到token字符串后,會(huì)還原成客戶用戶信息開始驗(yàn)證,驗(yàn)證成功后會(huì)根據(jù)當(dāng)前用戶生成特定的響應(yīng)內(nèi)容;

安裝JWT相關(guān)的包
1、jsonwebtoken:用于生成JWT字符串;
2、express-jwt:用于將JWT字符串還原為JSON對(duì)象;

npm i jsonwebtoken express-jwt  

3、導(dǎo)入jsonwebtoken express-jwt 模塊

// TODO_01:安裝并導(dǎo)入 JWT 相關(guān)的兩個(gè)包,分別是 jsonwebtoken 和 express-jwt
const jwt = require('jsonwebtoken') //用于生成token字符串
const expressJWT = require('express-jwt') //用于將token字符串還原成json對(duì)象

4、定義secret密鑰,對(duì)JWT字符串進(jìn)行加密;

// TODO_02:定義 secret 密鑰,建議將密鑰命名為 secretKey
const secretKey = 'itheima No1 ^-^'

5、在登錄成功之后,調(diào)用 jwt.sign() 方法生成 JWT 字符串。并通過 token 屬性發(fā)送給客戶端

// 登錄接口
app.post('/api/login', function (req, res) {
  // 將 req.body 請(qǐng)求體中的數(shù)據(jù),轉(zhuǎn)存為 userinfo 常量
  const userinfo = req.body
  // 登錄失敗
  if (userinfo.username !== 'admin' || userinfo.password !== '000000') {
    return res.send({
      status: 400,
      message: '登錄失敗!'
    })
  }
  // 登錄成功
  // TODO_03:在登錄成功之后,調(diào)用 jwt.sign() 方法生成 JWT 字符串。并通過 token 屬性發(fā)送給客戶端
  // 參數(shù)1:用戶的信息對(duì)象
  // 參數(shù)2:加密的密鑰
  // 參數(shù)3:配置對(duì)象,可以配置當(dāng)權(quán) token 的有效期 30s 30秒過后失效
  const tokenStr = jwt.sign({ username: userinfo.username},secretKey, { expiresIn: '30s'})
  res.send({
    status: 200,
    message: '登錄成功!',
    token: 'tokenStr' // 要發(fā)送給客戶端的 token 字符串
  })
})

6、注冊(cè)將 JWT 字符串解析還原成 JSON 對(duì)象的中間件;

// TODO_04:注冊(cè)將 JWT 字符串解析還原成 JSON 對(duì)象的中間件
// expressJWT({secret:'secretKey'}) 就是用來解析 token 的中間件
// .unless({path: [/^\/api/] }) 用來指定哪些接口不需要訪問權(quán)限
// 注意:只要配置成功了express-jwt 這個(gè)中間件,就可以解析出來的用戶信息,掛載到req.user屬性上
app.use(expressJWT({secret: secretKey, algorithms:['HS256'] }).unless({path: [/^\/api/] }))

6、使用 req.user 獲取用戶信息,并使用 data 屬性將用戶信息發(fā)送給客戶端

// 這是一個(gè)有權(quán)限的 API 接口
app.get('/admin/getinfo', function (req, res) {
  // TODO_05:使用 req.user 獲取用戶信息,并使用 data 屬性將用戶信息發(fā)送給客戶端
  console.log(req.user)
  res.send({
    status: 200,
    message: '獲取用戶信息成功!',
    data: req.user // 要發(fā)送給客戶端的用戶信息
  })
})

9、錯(cuò)誤中間件

// TODO_06:使用全局錯(cuò)誤處理中間件,捕獲解析 JWT 失敗后產(chǎn)生的錯(cuò)誤
app.use((err, req, res, next) => {
  // 這次錯(cuò)誤是由 token 解析失敗導(dǎo)致的
  if(err.name === 'UnauthorizedError') {
    return res.send({
      status: 401,
      message: '無效的token'
    })

    res.send({
      status: 500,
      message: '未知的錯(cuò)誤'
    })
  }
})
jwt驗(yàn)證-token字符串的加密與解析
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容