摘要:什么是官方給出的定義是是一個(gè)開放標(biāo)準(zhǔn),它定義了一種緊湊的獨(dú)立的方式,用于安全地在當(dāng)事人之間傳遞信息作為一個(gè)對(duì)象。結(jié)構(gòu)由下面三個(gè)部分組成一個(gè)字符串通常由兩個(gè)部分組成令牌的,即,以及正在使用的散列算法,如或。
什么是JSON Web Token ?
官方給出的定義是:
JSON Web Token(JWT)是一個(gè)開放標(biāo)準(zhǔn)(RFC 7519),它定義了一種緊湊的、獨(dú)立的方式,用于安全地在當(dāng)事人之間傳遞信息作為一個(gè)JSON對(duì)象。這些信息可以被驗(yàn)證和信任,因?yàn)樗菙?shù)字簽名的。JWTs可以使用一個(gè)secret (使用HMAC算法)或使用RSA的公鑰/私鑰對(duì)來(lái)簽名。 文中我們使用公私鑰的加密方式。
由下面三個(gè)部分組成一個(gè)token字符串
Header
header通常由兩個(gè)部分組成:令牌的type,即JWT,以及正在使用的散列算法,如HMAC SHA256或RSA。
Payload ,包含三個(gè)類型,自定義部分可以存儲(chǔ)一些信息,如:用戶信息、角色等;
Registered claims:已注冊(cè)的,具體屬性,點(diǎn)擊傳送
Public claims:自定義的,具體屬性,點(diǎn)擊傳送
Private claims:這是在同意使用它們的各方之間共享信息的自定義聲明,并且既沒有注冊(cè)也沒有公開聲明。
Signature
使用header、payload和secret生成一個(gè)簽名
工作流程這里直接使用官網(wǎng)的圖
使用json傳輸數(shù)據(jù),因此在編碼時(shí),也會(huì)更小
更安全
無(wú)需在服務(wù)端保存相關(guān)信息,只需要驗(yàn)證token是否有效即可
代碼實(shí)現(xiàn)這里使用express來(lái)創(chuàng)建一個(gè)服務(wù)
創(chuàng)建一個(gè)入口文件,主要用于一些中間件的掛載
//index.js const express = require("express") const app = express() // 使用body-parser獲取請(qǐng)求body const bodyParser = require("body-parser"); const cookieParser = require("cookie-parser") // 引入路由中間件 const routerAdmin = require("./app/router-admin") app.use(bodyParser.json()); // for parsing application/json app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded app.use(cookieParser()) // 加載路由模塊 app.use("/admin",routerAdmin); app.listen(3000,function(){ console.log("port 3000 start") })
然后創(chuàng)建一個(gè) app/router-admin.js 生成需要用到認(rèn)證的路由中間件,這里我是在mongodb中取的用戶信息,也可以自行模擬數(shù)據(jù)
//router-admin.js const express = require("express") const router = express.Router() var MongoClient = require("mongodb").MongoClient; const jwt = require("jsonwebtoken") const fs = require("fs") // const secretStr = "sdfsjfklsjfiewjwoieow" // 根據(jù)mongodb生成的_id查詢數(shù)據(jù) var ObjectId = require("mongodb").ObjectId var url = "mongodb://localhost:27017/"; var payload = { user : "william", admin : true } router.post("/login",function(req,res){ let name = req.body.name, pwd = req.body.pwd; var cert = fs.readFileSync("./private.key") MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("blog"); var noSqlStr = {name:name,pwd:pwd} dbo.collection("userlist"). find(noSqlStr).toArray(function(err, result) { // 返回集合中所有數(shù)據(jù) if (err) throw err; // console.log(result); // 驗(yàn)證通過(guò),服務(wù)端回傳token if(!!result.length){ var token = jwt.sign(payload, cert, { algorithm: "RS256" ,expiresIn:"30s"}); res.send({ status : true, msg : "", token : token }) } db.close(); }); }); }) // 驗(yàn)證jsonwebtoken是否過(guò)期的中間件,在login接口后面執(zhí)行,除了login接口的請(qǐng)求外,其他接口都需要驗(yàn)證token router.use(function jwtVerify(req, res, next) { let token = req.get("token") console.log(token) var cert = fs.readFileSync("./public.key"); // 先解密 jwt.verify(token, cert,function(err,decoded){ if(err || !decoded) res.send({data:null,status:false,msg:err}) if(decoded.user == payload.user){ next(); } }); }); router.get("/search",function(req,res){ res.send({data:"查詢成功",msg:"",status:true}) }) module.exports = router
因?yàn)檫@里使用的是公私鑰的加密方式,需使用ssh-keygen生成公私鑰
私鑰生成:ssh-keygen -t rsa -b 2048 -f private.key 公鑰生成:openssl rsa -in private.key -pubout -outform PEM -out public.key完整項(xiàng)目地址 參考
https://jwt.io/introduction/
https://tools.ietf.org/html/r...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95364.html
摘要:權(quán)限控制業(yè)務(wù)需求查看用戶列表接口管理員才能使用更新用戶信息接口當(dāng)前對(duì)應(yīng)用戶才能調(diào)用這時(shí)候需要需要加入中間件來(lái)實(shí)現(xiàn)權(quán)限控制這時(shí)候咱們需要學(xué)習(xí)了解下課前學(xué)習(xí)了解入門教程基于的認(rèn)證版實(shí)現(xiàn)本文中使用了插件現(xiàn)將服務(wù)邏輯代碼附上服務(wù)配置設(shè)置創(chuàng) 權(quán)限控制 業(yè)務(wù)需求:查看用戶列表接口(管理員才能使用)、更新用戶信息接口(當(dāng)前對(duì)應(yīng)用戶才能調(diào)用) 這時(shí)候需要需要加入中間件來(lái)實(shí)現(xiàn)權(quán)限控制: showImg(...
摘要:用于方便地搭建能夠處理超高并發(fā)擴(kuò)展性極高的動(dòng)態(tài)應(yīng)用服務(wù)和動(dòng)態(tài)網(wǎng)關(guān)。 介紹 權(quán)限認(rèn)證是接口開發(fā)中不可避免的問(wèn)題,權(quán)限認(rèn)證包括兩個(gè)方面 接口需要知道調(diào)用的用戶是誰(shuí) 接口需要知道該用戶是否有權(quán)限調(diào)用 第1個(gè)問(wèn)題偏向于架構(gòu),第2個(gè)問(wèn)題更偏向于業(yè)務(wù),因此考慮在架構(gòu)層解決第1個(gè)問(wèn)題,以達(dá)到以下目的 所有請(qǐng)求被保護(hù)的接口保證是合法的(已經(jīng)認(rèn)證過(guò)的用戶) 接口可以從請(qǐng)求頭中獲取當(dāng)前用戶信息 每個(gè)...
摘要:一步一步構(gòu)建一個(gè)應(yīng)用開篇地址基于的認(rèn)證流程客戶端用戶發(fā)登錄請(qǐng)求服務(wù)端驗(yàn)證用戶名密碼驗(yàn)證成功服務(wù)端生成一個(gè),響應(yīng)給客戶端客戶端之后的每次請(qǐng)求中都帶上這個(gè)服務(wù)端對(duì)需要認(rèn)證的接口要驗(yàn)證,驗(yàn)證成功接收請(qǐng)求這里我們采用來(lái)生成,使用驗(yàn)證驗(yàn)證成功會(huì)把 [一步一步構(gòu)建一個(gè)react應(yīng)用-開篇](https://segmentfault.com/a/11... git地址 基于token的認(rèn)證流程 客...
摘要:一步一步構(gòu)建一個(gè)應(yīng)用開篇地址基于的認(rèn)證流程客戶端用戶發(fā)登錄請(qǐng)求服務(wù)端驗(yàn)證用戶名密碼驗(yàn)證成功服務(wù)端生成一個(gè),響應(yīng)給客戶端客戶端之后的每次請(qǐng)求中都帶上這個(gè)服務(wù)端對(duì)需要認(rèn)證的接口要驗(yàn)證,驗(yàn)證成功接收請(qǐng)求這里我們采用來(lái)生成,使用驗(yàn)證驗(yàn)證成功會(huì)把 [一步一步構(gòu)建一個(gè)react應(yīng)用-開篇](https://segmentfault.com/a/11... git地址 基于token的認(rèn)證流程 客...
閱讀 3060·2021-10-12 10:12
閱讀 5394·2021-09-26 10:20
閱讀 1527·2021-07-26 23:38
閱讀 2818·2019-08-30 15:54
閱讀 1650·2019-08-30 13:45
閱讀 1968·2019-08-30 11:23
閱讀 3092·2019-08-29 13:49
閱讀 836·2019-08-26 18:23