日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Node.js應用:Koa2使用JWT進行鑒權

在前后端分離的開發(fā)中,通過 Restful API 進行數(shù)據(jù)交互時,如果沒有對 API 進行保護,那么別人就可以很容易地獲取并調(diào)用這些 API 進行操作。那么服務器端要如何進行鑒權呢?

成都做網(wǎng)站、成都網(wǎng)站設計,成都做網(wǎng)站公司-創(chuàng)新互聯(lián)公司已向上千家企業(yè)提供了,網(wǎng)站設計,網(wǎng)站制作,網(wǎng)絡營銷等服務!設計與技術結合,多年網(wǎng)站推廣經(jīng)驗,合理的價格為您打造企業(yè)品質(zhì)網(wǎng)站。

Json Web Token 簡稱為 JWT,它定義了一種用于簡潔、自包含的用于通信雙方之間以 JSON 對象的形式安全傳遞信息的方法。JWT 可以使用 HMAC 算法或者是 RSA 的公鑰密鑰對進行簽名。

說得好像跟真的一樣,那么到底要怎么進行認證呢?

首先用戶登錄時,輸入用戶名和密碼后請求服務器登錄接口,服務器驗證用戶名密碼正確后,生成token并返回給前端,前端存儲token,并在后面的請求中把token帶在請求頭中傳給服務器,服務器驗證token有效,返回正確數(shù)據(jù)。

既然服務器端使用 Koa2 框架進行開發(fā),除了要使用到 jsonwebtoken 庫之外,還要使用一個 koa-jwt 中間件,該中間件針對 Koa 對 jsonwebtoken 進行了封裝,使用起來更加方便。下面就來看看是如何使用的。

生成token

這里注冊了個 /login 的路由,用于用戶登錄時獲取token。

 
 
 
 
  1. const router = require('koa-router')(); 
  2. const jwt = require('jsonwebtoken'); 
  3. const userModel = require('../models/userModel.js'); 
  4. router.post('/login', async (ctx) => { 
  5.     const data = ctx.request.body; 
  6.     if(!data.name || !data.password){ 
  7.         return ctx.body = { 
  8.             code: '000002', 
  9.             data: null, 
  10.             msg: '參數(shù)不合法' 
  11.         } 
  12.     } 
  13.     const result = await userModel.findOne({ 
  14.         name: data.name, 
  15.         password: data.password 
  16.     }) 
  17.     if(result !== null){ 
  18.         const token = jwt.sign({ 
  19.             name: result.name, 
  20.             _id: result._id 
  21.         }, 'my_token', { expiresIn: '2h' }); 
  22.         return ctx.body = { 
  23.             code: '000001', 
  24.             data: token, 
  25.             msg: '登錄成功' 
  26.         } 
  27.     }else{ 
  28.         return ctx.body = { 
  29.             code: '000002', 
  30.             data: null, 
  31.             msg: '用戶名或密碼錯誤' 
  32.         } 
  33.     } 
  34. }); 
  35. module.exports = router; 

在驗證了用戶名密碼正確之后,調(diào)用 jsonwebtoken 的 sign() 方法來生成token,接收三個參數(shù),第一個是載荷,用于編碼后存儲在 token 中的數(shù)據(jù),也是驗證 token 后可以拿到的數(shù)據(jù);第二個是密鑰,自己定義的,驗證的時候也是要相同的密鑰才能解碼;第三個是options,可以設置 token 的過期時間。

獲取token

接下來就是前端獲取 token,這里是在 vue.js 中使用 axios 進行請求,請求成功之后拿到 token 保存到 localStorage 中。這里登錄成功后,還把當前時間存了起來,除了判斷 token 是否存在之外,還可以再簡單的判斷一下當前 token 是否過期,如果過期,則跳登錄頁面

 
 
 
 
  1. submit(){ 
  2.     axios.post('/login', { 
  3.         name: this.username, 
  4.         password: this.password 
  5.     }).then(res => { 
  6.         if(res.code === '000001'){ 
  7.             localStorage.setItem('token', res.data); 
  8.             localStorage.setItem('token_exp', new Date().getTime()); 
  9.             this.$router.push('/'); 
  10.         }else{ 
  11.             alert(res.msg); 
  12.         } 
  13.     }) 

然后請求服務器端API的時候,把 token 帶在請求頭中傳給服務器進行驗證。每次請求都要獲取 localStorage 中的 token,這樣很麻煩,這里使用了 axios 的請求攔截器,對每次請求都進行了取 token 放到 headers 中的操作。

 
 
 
 
  1. axios.interceptors.request.use(config => { 
  2.     const token = localStorage.getItem('token'); 
  3.     config.headers.common['Authorization'] = 'Bearer ' + token; 
  4.     return config; 
  5. }) 

驗證token

通過 koa-jwt 中間件來進行驗證,用法也非常簡單

 
 
 
 
  1. const koa = require('koa'); 
  2. const koajwt = require('koa-jwt'); 
  3. const app = new koa(); 
  4. // 錯誤處理 
  5. app.use((ctx, next) => { 
  6.     return next().catch((err) => { 
  7.         if(err.status === 401){ 
  8.             ctx.status = 401; 
  9.             ctx.body = 'Protected resource, use Authorization header to get access\n'; 
  10.         }else{ 
  11.             throw err; 
  12.         } 
  13.     }) 
  14. }) 
  15. app.use(koajwt({ 
  16.     secret: 'my_token' 
  17. }).unless({ 
  18.     path: [/\/user\/login/] 
  19. })); 

通過 app.use 來調(diào)用該中間件,并傳入密鑰 {secret: 'my_token'},unless 可以指定哪些 URL 不需要進行 token 驗證。token 驗證失敗的時候會拋出401錯誤,因此需要添加錯誤處理,而且要放在 app.use(koajwt()) 之前,否則不執(zhí)行。

如果請求時沒有token或者token過期,則會返回401。

解析koa-jwt

我們上面使用 jsonwebtoken 的 sign() 方法來生成 token 的,那么 koa-jwt 做了些什么幫我們來驗證 token。

resolvers/auth-header.js

 
 
 
 
  1. module.exports = function resolveAuthorizationHeader(ctx, opts) { 
  2.     if (!ctx.header || !ctx.header.authorization) { 
  3.         return; 
  4.     } 
  5.     const parts = ctx.header.authorization.split(' '); 
  6.     if (parts.length === 2) { 
  7.         const scheme = parts[0]; 
  8.         const credentials = parts[1]; 
  9.         if (/^Bearer$/i.test(scheme)) { 
  10.             return credentials; 
  11.         } 
  12.     } 
  13.     if (!opts.passthrough) { 
  14.         ctx.throw(401, 'Bad Authorization header format. Format is "Authorization: Bearer "'); 
  15.     } 
  16. }; 

在 auth-header.js 中,判斷請求頭中是否帶了 authorization,如果有,將 token 從 authorization 中分離出來。如果沒有 authorization,則代表了客戶端沒有傳 token 到服務器,這時候就拋出 401 錯誤狀態(tài)。

verify.js

 
 
 
 
  1. const jwt = require('jsonwebtoken'); 
  2. module.exports = (...args) => { 
  3.     return new Promise((resolve, reject) => { 
  4.         jwt.verify(...args, (error, decoded) => { 
  5.             error ? reject(error) : resolve(decoded); 
  6.         }); 
  7.     }); 
  8. }; 

在 verify.js 中,使用 jsonwebtoken 提供的 verify() 方法進行驗證返回結果。jsonwebtoken 的 sign() 方法來生成 token 的,而 verify() 方法則是用來認證和解析 token。如果 token 無效,則會在此方法被驗證出來。

index.js

 
 
 
 
  1. const decodedToken = await verify(token, secret, opts); 
  2. if (isRevoked) { 
  3.     const tokenRevoked = await isRevoked(ctx, decodedToken, token); 
  4.     if (tokenRevoked) { 
  5.         throw new Error('Token revoked'); 
  6.     } 
  7. ctx.state[key] = decodedToken;  // 這里的key = 'user' 
  8. if (tokenKey) { 
  9.     ctx.state[tokenKey] = token; 

在 index.js 中,調(diào)用 verify.js 的方法進行驗證并解析 token,拿到上面進行 sign() 的數(shù)據(jù) {name: result.name, _id: result._id},并賦值給 ctx.state.user,在控制器中便可以直接通過 ctx.state.user 拿到 name 和 _id。

安全性

如果 JWT 的加密密鑰泄露的話,那么就可以通過密鑰生成 token,隨意的請求 API 了。因此密鑰絕對不能存在前端代碼中,不然很容易就能被找到。

在 HTTP 請求中,token 放在 header 中,中間者很容易可以通過抓包工具抓取到 header 里的數(shù)據(jù)。而 HTTPS 即使能被抓包,但是它是加密傳輸?shù)模砸材貌坏?token,就會相對安全了。

總結

這上面就是 jwt 基本的流程,這或許不是最完美的,但在大多數(shù)登錄中使用已經(jīng)足夠了。

上面的代碼可能不夠具體,這里使用 Koa + mongoose + vue.js 實現(xiàn)的一個例子 : jwt-demo,可以做為參考。

【本文為專欄作者“林鑫”的原創(chuàng)稿件,轉載請通過微信公眾號聯(lián)系作者獲取授權】


當前題目:Node.js應用:Koa2使用JWT進行鑒權
當前鏈接:http://www.5511xx.com/article/djisjih.html