偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Node.js 應(yīng)用:Koa2 使用 JWT 進行鑒權(quán)

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

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

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

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

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

既然服務(wù)器端使用 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,可以設(shè)置 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.     }) 

然后請求服務(wù)器端API的時候,把 token 帶在請求頭中傳給服務(wù)器進行驗證。每次請求都要獲取 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 <token>"'); 
  15.     } 
  16. }; 

在 auth-header.js 中,判斷請求頭中是否帶了 authorization,如果有,將 token 從 authorization 中分離出來。如果沒有 authorization,則代表了客戶端沒有傳 token 到服務(wù)器,這時候就拋出 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() 方法進行驗證返回結(jié)果。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,就會相對安全了。

總結(jié)

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

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

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

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2016-08-25 21:28:04

前端node截圖

2021-06-15 15:03:21

MongoDBNode.jsCRUD

2013-03-28 14:54:36

2016-09-18 16:04:24

HTTPNode應(yīng)用

2018-04-20 16:15:42

Koa2上傳下載

2017-04-18 09:27:14

Visual StudNode.js調(diào)試

2022-08-28 16:30:34

Node.jsDocker指令

2015-03-10 10:59:18

Node.js開發(fā)指南基礎(chǔ)介紹

2013-11-01 09:34:56

Node.js技術(shù)

2023-01-10 14:11:26

2019-07-24 09:28:36

Node.jskoa架構(gòu)

2011-07-26 11:07:08

JavaScript

2019-05-05 11:47:09

TypeScript開發(fā)Node.js

2020-09-04 15:06:04

Docker容器化Node.js

2017-06-20 15:39:58

Koa2 應(yīng)用動態(tài)Swagger文檔

2017-05-10 09:40:57

Ubuntupm2Nginx

2022-12-14 14:40:27

Node.js開發(fā)應(yīng)用程序

2021-03-03 06:39:05

Nodejs前端開發(fā)

2021-07-16 04:56:03

NodejsAddon

2012-09-29 11:13:15

Node.JS前端開發(fā)Node.js打包
點贊
收藏

51CTO技術(shù)棧公眾號