詳解JWT與Token的應(yīng)用與原理
前言:JWT全稱“JSON Web Token”,是實(shí)現(xiàn)Token的機(jī)制。官網(wǎng):https://jwt.io/
JWT的應(yīng)用
- JWT用于登錄身份驗(yàn)證。
- 用戶登錄成功后,后端通過JWT機(jī)制生成一個(gè)token,返回給客戶端。
- 客戶端后續(xù)的每次請(qǐng)求都需要攜帶token,攜帶在authorization中。
- 后端從authorization中拿到token后,通過secretKey進(jìn)行解密驗(yàn)證身份。
Token的組成原理
JWT生成的Token由三部分組成:header payload signature
- header
- alg:指定signature采用的加密算法,默認(rèn)是HS256,對(duì)稱加密(加密和解密的密鑰相同)
- typ:固定值,通常是JWT
- 通過base64Url算法進(jìn)行編碼
- payload
- 用戶id和name
- 默認(rèn)攜帶iat,令牌簽發(fā)時(shí)間(時(shí)間戳)
- exp設(shè)置令牌過期時(shí)間
- 通過base64Url算法進(jìn)行編碼
- signature
- 設(shè)置一個(gè)secretKey,通過將前兩個(gè)結(jié)果合并后進(jìn)行HS256算法
- signature的組成:
HS256(baseUrl64(header)+'.'+baseUrl(payload)+','+secretKey)
- secreKey一定不能暴露,因?yàn)榭梢灶C發(fā)token,也可以解密
采用HS256對(duì)稱加密生成的Token(https://jwt.io/)
JWT對(duì)稱加密
JWT默認(rèn)使用的是HS256對(duì)稱加密,其中secretKey是密鑰,意味著公鑰和私鑰都是同一個(gè),這樣安全性不高。
例如在分布式服務(wù)中,其他系統(tǒng)服務(wù)器雖然可以用secretKey驗(yàn)證token,但是這樣不安全,因?yàn)椴捎玫氖菍?duì)稱加密算法,每個(gè)服務(wù)器都可以通secretKey頒發(fā)token,黑客只要攻破任何一個(gè)服務(wù)器就可以拿到secretKey。
JWT非對(duì)稱加密
所以我們需要使用非對(duì)稱加密,加密和解密的密鑰不一致。加密密鑰稱為“私鑰”,解密密鑰稱為“公鑰”。
采用RS256非對(duì)稱加密生成的Token(https://jwt.io/)
生成私鑰和公鑰
mac電腦直接使用終端
windows電腦安裝git,使用git bash終端。
- 輸入openssl
- 輸入
genrsa -out private.key 2048
生成私鑰 - 輸入
rsa -in private.key -pubout -out public.key
生成公鑰
代碼中加密使用的算法需要修改為RS256非對(duì)稱加密算法(注意:RS256最小密鑰大小為2048位)
nodejs中實(shí)現(xiàn)JWT(token非對(duì)稱加密)
const Koa = require('koa') const KoaRouter = require('@koa/router') const jwt = require('jsonwebtoken'); const fs = require('fs') const app = new Koa(); const loginRouter = new KoaRouter({ prefix: '/login' }) const usersRouter = new KoaRouter({ prefix: '/users' }) const privateKey = fs.readFileSync('./keys/private.key') const publicKey = fs.readFileSync('./keys/public.key') // login接口 loginRouter.post('/', (ctx, next) => { const payload = { id: 1, name: 'zjc' } const token = jwt.sign(payload, privateKey, { expiresIn: 3000, algorithm: 'RS256' }) ctx.body = { message: '登錄成功', code: 200, token } }) // users接口 usersRouter.get('/', (ctx, next) => { const token = ctx.header.authorization.replace('Bearer ', '') console.log(token); try { // 驗(yàn)證token jwt.verify(token, publicKey) ctx.body = { code: 200, data: ['xx', 'yy'] } } catch (error) { ctx.body = { code: -1001, message: 'token無效' } } }) app.use(loginRouter.routes()) app.use(usersRouter.routes()) app.listen(8000, () => { console.log('服務(wù)器啟動(dòng)成功'); })
到此這篇關(guān)于詳解JWT與Token的應(yīng)用與原理的文章就介紹到這了,更多相關(guān)JWT與Token應(yīng)用與原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Egret引擎開發(fā)指南之發(fā)布項(xiàng)目
當(dāng)我們制作完成一個(gè)項(xiàng)目后,我們需要把項(xiàng)目發(fā)布為正式版本,并放到網(wǎng)上提供給玩家。那么在egret中簡單的使用build命令并非打包最終的正式版文件。你還需要進(jìn)行最終的發(fā)布操作。2014-09-09nodejs中實(shí)現(xiàn)用戶注冊(cè)路由功能
這篇文章主要介紹了nodejs中實(shí)現(xiàn)用戶注冊(cè)路由功能的實(shí)例代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05學(xué)習(xí)使用grunt來打包JavaScript和CSS程序的教程
這篇文章主要介紹了學(xué)習(xí)使用grunt來打包JavaScript和CSS程序的教程,grunt基于node.js和需要的朋友可以參考下2016-01-01Node.js定時(shí)任務(wù)之node-schedule使用詳解
這篇文章主要介紹了Node.js定時(shí)任務(wù)之node-schedule使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08node基于async/await對(duì)mysql進(jìn)行封裝
這篇文章主要介紹了node基于async/await對(duì)mysql進(jìn)行封裝,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下2019-06-06koa-compose簡單實(shí)現(xiàn)及使用的妙處
這篇文章主要為大家介紹了koa-compose簡單實(shí)現(xiàn)及使用的妙處詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04