首頁 web前端 js教程 怎麼使用node實作基於token身份驗證

怎麼使用node實作基於token身份驗證

May 25, 2018 pm 02:50 PM
node 基於 實現

這次帶給大家怎麼使用node實作基於token身分驗證,使用node實作基於token身分驗證的注意事項有哪些,以下就是實戰案例,一起來看一下。

最近研究了下基於token的身份驗證,並將這種機制整合在個人專案中。現在很多網站的認證方式都從傳統的seesion cookie轉向token校驗。對比傳統的校驗方式,token確實有更好的擴展性與安全性。

傳統的session cookie驗證

#由於HTTP是無狀態的,它並不會記錄使用者的身分。使用者將帳號與密碼傳送給伺服器後,後台通過校驗,但是並沒有記錄狀態,於是下一次使用者的請求仍需要校驗身分。為了解決這個問題,需要在服務端產生一條包含使用者身分的記錄,也就是session,再將這條記錄傳送給使用者並儲存在使用者本地,即cookie。接下來使用者的請求都會帶上這條cookie,若客戶端的cookie與服務端的session能對應上,則表示使用者身分驗證通過。

token身分識別校驗

流程大致如下:

  1. 第一次要求時,使用者傳送帳號與密碼

  2. 後台校驗通過,則會產生一個有時效性的token,再將此token發送給用戶

  3. 用戶獲得token後,將此token儲存在本地,一般儲存在localstorage或cookie

  4. 之後的每次請求都會將此token加入在請求頭裡,所有需要校驗身分的介面都會被校驗token,若token解析後的資料包含使用者身份信息,則身份驗證通過。

比較傳統的校驗方式,token校驗有以下優勢:

  1. 在基於token的認證,token透過請求頭傳輸,而不是把認證資訊儲存在session或cookie中。這意味著無狀態。你可以從任何一種可以發送HTTP請求的終端向伺服器發送請求。

  2. 可以避免CSRF攻擊

  3. 當在應用程式中進行session的讀取,寫入或刪除操作時,會有一個檔案操作發生在作業系統的temp 資料夾下,至少在第一次時。假設有多台伺服器並且 session 在第一台服務上建立。當你再次發送請求並且這個請求落在另一台伺服器上,session 資訊並不存在並且會獲得一個「未認證」的回應。我知道,你可以透過一個黏性 session 來解決這個問題。然而,在基於 token 的認證中,這個問題很自然就被解決了。沒有黏性 session 的問題,因為在每個發送到伺服器的請求中這個請求的 token 都會被攔截。

以下介紹利用node jwt(jwt教學)來建構簡易的token身分校驗

範例

當用戶第一次登入時,提交帳號與密碼至伺服器,伺服器校驗通過,則產生對應的token,代碼如下:

const fs = require('fs');
const path = require('path');
const jwt = require('jsonwebtoken');
//生成token的方法
function generateToken(data){
  let created = Math.floor(Date.now() / 1000);
  let cert = fs.readFileSync(path.join(dirname, '../config/pri.pem'));//私钥
  let token = jwt.sign({
    data,
    exp: created + 3600 * 24
  }, cert, {algorithm: 'RS256'});
  return token;
}
//登录接口
router.post('/oa/login', async (ctx, next) => {
  let data = ctx.request.body;
  let {name, password} = data;
  let sql = 'SELECT uid FROM t_user WHERE name=? and password=? and is_delete=0', value = [name, md5(password)];
  await db.query(sql, value).then(res => {
    if (res && res.length > 0) {
      let val = res[0];
      let uid = val['uid'];
      let token = generateToken({uid});
      ctx.body = {
        ...Tips[0], data: {token}
      }
    } else {
      ctx.body = Tips[1006];
    }
  }).catch(e => {
    ctx.body = Tips[1002];
  });
});
登入後複製

使用者透過校驗將取得的token存放在本機:

store.set('loginedtoken',token);//store为插件
登入後複製

之後客戶端請求需要驗證身份的接口,都會將token放在請求頭裡傳遞給服務端:

service.interceptors.request.use(config => {
  let params = config.params || {};
  let loginedtoken = store.get('loginedtoken');
  let time = Date.now();
  let {headers} = config;
  headers = {...headers,loginedtoken};
  params = {...params,_:time};
  config = {...config,params,headers};
  return config;
}, error => {
  Promise.reject(error);
})
登入後複製

服務端對所有需要登錄的接口均攔截token併校驗合法性。

function verifyToken(token){
  let cert = fs.readFileSync(path.join(dirname, '../config/pub.pem'));//公钥
  try{
    let result = jwt.verify(token, cert, {algorithms: ['RS256']}) || {};
    let {exp = 0} = result,current = Math.floor(Date.now()/1000);
    if(current <= exp){
      res = result.data || {};
    }
  }catch(e){
  }
  return res;
}
app.use(async(ctx, next) => {
  let {url = ''} = ctx;
  if(url.indexOf('/user/') > -1){//需要校验登录态
    let header = ctx.request.header;
    let {loginedtoken} = header;
    if (loginedtoken) {
      let result = verifyToken(loginedtoken);
      let {uid} = result;
      if(uid){
        ctx.state = {uid};
        await next();
      }else{
        return ctx.body = Tips[1005];
      }
    } else {
      return ctx.body = Tips[1005];
    }
  }else{
    await next();
  }
});
登入後複製

本範例使用的公鑰與私鑰可自行生成,操作如下:

  1. #開啟命令列工具,輸入openssl,開啟openssl;

  2. #產生私鑰:genrsa -out rsa_private_key.pem 2048

  3. 產生公鑰: rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

Angular專案中使用scss步驟詳解

怎麼使用vue2.0 koa2 mongodb實作註冊登陸

#

以上是怎麼使用node實作基於token身份驗證的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

華為手機如何實現雙微信登入? 華為手機如何實現雙微信登入? Mar 24, 2024 am 11:27 AM

華為手機如何實現雙微信登入?隨著社群媒體的興起,微信已成為人們日常生活中不可或缺的溝通工具之一。然而,許多人可能會遇到一個問題:在同一部手機上同時登入多個微信帳號。對於華為手機用戶來說,實現雙微信登入並不困難,本文將介紹華為手機如何實現雙微信登入的方法。首先,華為手機自帶的EMUI系統提供了一個很方便的功能-應用程式雙開。透過應用程式雙開功能,用戶可以在手機上同

使用Java編寫程式碼實作愛心動畫 使用Java編寫程式碼實作愛心動畫 Dec 23, 2023 pm 12:09 PM

透過Java程式碼實現愛心動畫效果在程式設計領域中,動畫效果是非常常見且受歡迎的。可以透過Java程式碼實現各種各樣的動畫效果,其中之一就是愛心動畫效果。本文將介紹如何使用Java程式碼來實現此效果,並給出具體的程式碼範例。實現愛心動畫效果的關鍵在於繪製心形圖案,並透過改變心形的位置和顏色來實現動畫效果。下面是一個簡單範例的程式碼:importjavax.swing.

PHP程式設計指南:實作斐波那契數列的方法 PHP程式設計指南:實作斐波那契數列的方法 Mar 20, 2024 pm 04:54 PM

程式語言PHP是一種用於Web開發的強大工具,能夠支援多種不同的程式設計邏輯和演算法。其中,實作斐波那契數列是一個常見且經典的程式設計問題。在這篇文章中,將介紹如何使用PHP程式語言來實作斐波那契數列的方法,並附上具體的程式碼範例。斐波那契數列是一個數學上的序列,其定義如下:數列的第一個和第二個元素為1,從第三個元素開始,每個元素的值等於前兩個元素的和。數列的前幾元

如何在華為手機上實現微信分身功能 如何在華為手機上實現微信分身功能 Mar 24, 2024 pm 06:03 PM

如何在華為手機上實現微信分身功能隨著社群軟體的普及和人們對隱私安全的日益重視,微信分身功能逐漸成為人們關注的焦點。微信分身功能可以幫助使用者在同一台手機上同時登入多個微信帳號,方便管理和使用。在華為手機上實現微信分身功能並不困難,只需要按照以下步驟操作即可。第一步:確保手機系統版本和微信版本符合要求首先,確保你的華為手機系統版本已更新至最新版本,以及微信App

Pi Node教學:什麼是Pi節點?如何安裝和設定Pi Node? Pi Node教學:什麼是Pi節點?如何安裝和設定Pi Node? Mar 05, 2025 pm 05:57 PM

PiNetwork節點詳解及安裝指南本文將詳細介紹PiNetwork生態系統中的關鍵角色——Pi節點,並提供安裝和配置的完整步驟。 Pi節點在PiNetwork區塊鏈測試網推出後,成為眾多先鋒積極參與測試的重要環節,為即將到來的主網發布做準備。如果您還不了解PiNetwork,請參考Pi幣是什麼?上市價格多少? Pi用途、挖礦及安全性分析。什麼是PiNetwork? PiNetwork項目始於2019年,擁有其專屬加密貨幣Pi幣。該項目旨在創建一個人人可參與

開發建議:如何利用ThinkPHP框架實現非同步任務 開發建議:如何利用ThinkPHP框架實現非同步任務 Nov 22, 2023 pm 12:01 PM

《開發建議:如何利用ThinkPHP框架實現非同步任務》隨著網路技術的快速發展,Web應用程式對於處理大量並發請求和複雜業務邏輯的需求也越來越高。為了提高系統的效能和使用者體驗,開發人員常常會考慮利用非同步任務來執行一些耗時操作,例如發送郵件、處理文件上傳、產生報表等。在PHP領域,ThinkPHP框架作為一個流行的開發框架,提供了一些便捷的方式來實現非同步任務。

掌握Golang如何實現遊戲開發的可能性 掌握Golang如何實現遊戲開發的可能性 Mar 16, 2024 pm 12:57 PM

在現今的軟體開發領域中,Golang(Go語言)作為一種高效、簡潔、並發性強的程式語言,越來越受到開發者的青睞。其豐富的標準庫和高效的並發特性使它成為遊戲開發領域的一個備受關注的選擇。本文將探討如何利用Golang來實現遊戲開發,並透過具體的程式碼範例來展示其強大的可能性。 1.Golang在遊戲開發中的優勢作為靜態類型語言,Golang正在建構大型遊戲系統

如何在Golang中實現精確除法運算 如何在Golang中實現精確除法運算 Feb 20, 2024 pm 10:51 PM

在Golang中實現精確除法運算是一個常見的需求,特別是在涉及金融計算或其它需要高精度計算的場景中。 Golang的內建的除法運算子「/」是針對浮點數計算的,並且有時會出現精度遺失的問題。為了解決這個問題,我們可以藉助第三方函式庫或自訂函數來實現精確除法運算。一種常見的方法是使用math/big套件中的Rat類型,它提供了分數的表示形式,可以用來實現精確的除法運算

See all articles