最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Node.js Koa2使用JWT進行鑒權(quán)的方法示例

 更新時間:2018年08月17日 08:35:58   作者:林鑫  
這篇文章主要介紹了Node.js Koa2使用JWT進行鑒權(quán)的方法示例,小編覺得挺不錯的,現(xià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。

const router = require('koa-router')();
const jwt = require('jsonwebtoken');
const userModel = require('../models/userModel.js');

router.post('/login', async (ctx) => {
  const data = ctx.request.body;
  if(!data.name || !data.password){
    return ctx.body = {
      code: '000002',
      data: null,
      msg: '參數(shù)不合法'
    }
  }
  const result = await userModel.findOne({
    name: data.name,
    password: data.password
  })
  if(result !== null){
    const token = jwt.sign({
      name: result.name,
      _id: result._id
    }, 'my_token', { expiresIn: '2h' });
    return ctx.body = {
      code: '000001',
      data: token,
      msg: '登錄成功'
    }
  }else{
    return ctx.body = {
      code: '000002',
      data: null,
      msg: '用戶名或密碼錯誤'
    }
  }
});

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 是否過期,如果過期,則跳登錄頁面

submit(){
  axios.post('/login', {
    name: this.username,
    password: this.password
  }).then(res => {
    if(res.code === '000001'){
      localStorage.setItem('token', res.data);
      localStorage.setItem('token_exp', new Date().getTime());
      this.$router.push('/');
    }else{
      alert(res.msg);
    }
  })
}

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

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

驗證token

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

const koa = require('koa');
const koajwt = require('koa-jwt');
const app = new koa();

// 錯誤處理
app.use((ctx, next) => {
  return next().catch((err) => {
    if(err.status === 401){
      ctx.status = 401;
      ctx.body = 'Protected resource, use Authorization header to get access\n';
    }else{
      throw err;
    }
  })
})

app.use(koajwt({
  secret: 'my_token'
}).unless({
  path: [/\/user\/login/]
}));

通過 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
module.exports = function resolveAuthorizationHeader(ctx, opts) {
  if (!ctx.header || !ctx.header.authorization) {
    return;
  }
  const parts = ctx.header.authorization.split(' ');
  if (parts.length === 2) {
    const scheme = parts[0];
    const credentials = parts[1];
    if (/^Bearer$/i.test(scheme)) {
      return credentials;
    }
  }
  if (!opts.passthrough) {
    ctx.throw(401, 'Bad Authorization header format. Format is "Authorization: Bearer <token>"');
  }
};

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

verify.js

const jwt = require('jsonwebtoken');

module.exports = (...args) => {
  return new Promise((resolve, reject) => {
    jwt.verify(...args, (error, decoded) => {
      error ? reject(error) : resolve(decoded);
    });
  });
};

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

index.js

const decodedToken = await verify(token, secret, opts);
if (isRevoked) {
  const tokenRevoked = await isRevoked(ctx, decodedToken, token);
  if (tokenRevoked) {
    throw new Error('Token revoked');
  }
}
ctx.state[key] = decodedToken; // 這里的key = 'user'
if (tokenKey) {
  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 ,可以做為參考。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用node-canvas在服務(wù)端渲染echarts圖表解析

    使用node-canvas在服務(wù)端渲染echarts圖表解析

    這篇文章主要介紹了使用node-canvas在服務(wù)端渲染echarts圖表解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • nodejs對文件中的圖片進行歸類操作示例

    nodejs對文件中的圖片進行歸類操作示例

    這篇文章主要為大家介紹了nodejs對文件中的圖片進行歸類的實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • node.js基于express使用websocket的方法

    node.js基于express使用websocket的方法

    這篇文章主要介紹了node.js基于express使用websocket的方法,結(jié)合實例形式分析了node.js基于express調(diào)用websocket相關(guān)設(shè)置與使用操作技巧,需要的朋友可以參考下
    2017-11-11
  • node.js文件系統(tǒng)之文件寫入實例詳解

    node.js文件系統(tǒng)之文件寫入實例詳解

    Node.js和其他語言一樣,也有文件操作,下面這篇文章主要給大家介紹了關(guān)于node.js文件系統(tǒng)之文件寫入的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-03-03
  • 關(guān)于npm?i幾種常見命令的區(qū)別詳解

    關(guān)于npm?i幾種常見命令的區(qū)別詳解

    npm(Node.js Package Manager)是一個Node.js的包管理工具,用來解決Node.js代碼部署問題,下面這篇文章主要給大家介紹了關(guān)于npm?i幾種常見命令的那點事,需要的朋友可以參考下
    2023-03-03
  • 深入學(xué)習(xí)nodejs中的async模塊的使用方法

    深入學(xué)習(xí)nodejs中的async模塊的使用方法

    本篇文章主要介紹了nodejs中的async模塊的使用方法,具有一定的參考價值,有興趣的可以了解一下
    2017-07-07
  • Node.js高級編程cluster環(huán)境及源碼調(diào)試詳解

    Node.js高級編程cluster環(huán)境及源碼調(diào)試詳解

    這篇文章主要為大家介紹了Node.js高級編程cluster環(huán)境及源碼調(diào)試詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Node.js文件操作詳解

    Node.js文件操作詳解

    這篇文章主要介紹了Node.js文件操作詳解,本文講解了處理文件路徑講的一些方法、fs模塊詳細的使用和介紹等內(nèi)容,需要的朋友可以參考下
    2014-08-08
  • node.js超時timeout詳解

    node.js超時timeout詳解

    本文介紹了nodejs中超時timeout事件,并給出了詳細的示例分析,非常的詳盡,推薦給需要的小伙伴參考下
    2014-11-11
  • nodejs中的express-jwt的使用解讀

    nodejs中的express-jwt的使用解讀

    這篇文章主要介紹了nodejs中的express-jwt的使用解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評論

乐清市| 海宁市| 平武县| 盐山县| 汾阳市| 和龙市| 崇礼县| 唐海县| 朔州市| 苍山县| 锦屏县| 马边| 大厂| 荔波县| 南郑县| 西贡区| 乌恰县| 梁平县| 玉林市| 嘉鱼县| 大石桥市| 乌拉特后旗| 江川县| 雅江县| 玉山县| 舟山市| 金湖县| 龙井市| 武定县| 龙门县| 萍乡市| 灯塔市| 南岸区| 西丰县| 荣昌县| 怀来县| 阳信县| 威海市| 高清| 汕尾市| 泾川县|