koa+jwt實(shí)現(xiàn)token驗(yàn)證與刷新功能
JWT
JSON Web Token (JWT)是一個(gè)開放標(biāo)準(zhǔn)(RFC 7519),它定義了一種緊湊的、自包含的方式,用于作為JSON對(duì)象在各方之間安全地傳輸信息。該信息可以被驗(yàn)證和信任,因?yàn)樗菙?shù)字簽名的。
本文只講Koa2 + jwt的使用,不了解JWT的話請(qǐng)到這里)進(jìn)行了解。
koa環(huán)境
要使用koa2+jwt需要先有個(gè)koa的空環(huán)境,搭環(huán)境比較麻煩,我直接使用koa起手式,這是我使用koa+typescript搭建的空環(huán)境,如果你也經(jīng)常用koa寫寫小demo,可以點(diǎn)個(gè)star,方便~
安裝koa-jwt
koa-jwt主要作用是控制哪些路由需要jwt驗(yàn)證,哪些接口不需要驗(yàn)證:
import * as koaJwt from 'koa-jwt';
//路由權(quán)限控制 除了path里的路徑不需要驗(yàn)證token 其他都要
app.use(
koaJwt({
secret: secret.sign
}).unless({
path: [/^\/login/, /^\/register/]
})
);
上面代碼中,除了登錄、注冊(cè)接口不需要jwt驗(yàn)證,其他請(qǐng)求都需要。
使用jsonwebtoken生成、驗(yàn)證token
執(zhí)行npm install jsonwebtoken安裝jsonwebtoken
相關(guān)代碼:
import * as jwt from 'jsonwebtoken';
const secret = 'my_app_secret';
const payload = {user_name:'Jack', id:3, email: '1234@gmail.com'};
const token = jwt.sign(payload, secret, { expiresIn: '1h' });
上面代碼中通過jwt.sign來生成一個(gè)token,
參數(shù)意義:
- payload:載體,一般把用戶信息作為載體來生成token
- secret:秘鑰,可以是字符串也可以是文件
- expiresIn:過期時(shí)間 1h表示一小時(shí)
在登錄中返回token
import * as crypto from 'crypto';
import * as jwt from 'jsonwebtoken';
async login(ctx){
//從數(shù)據(jù)庫中查找對(duì)應(yīng)用戶
const user = await userRespository.findOne({
where: {
name: user.name
}
});
//密碼加密
const psdMd5 = crypto
.createHash('md5')
.update(user.password)
.digest('hex');
//比較密碼的md5值是否一致 若一致則生成token并返回給前端
if (user.password === psdMd5) {
//生成token
token = jwt.sign(user, secret, { expiresIn: '1h' });
//響應(yīng)到前端
ctx.body = {
token
}
}
}
前端攔截器
前端通過登錄拿到返回過來的token,可以將它存在localStorage里,然后再以后的請(qǐng)求中把token放在請(qǐng)求頭的Authorization里帶給服務(wù)端。
這里以axios請(qǐng)求為例,在發(fā)送請(qǐng)求時(shí),通過請(qǐng)求攔截器把token塞到header里:
//請(qǐng)求攔截器
axios.interceptors.request.use(function(config) {
//從localStorage里取出token
const token = localStorage.getItem('tokenName');
//把token塞入Authorization里
config.headers.Authorization = `Bearer ${token}`;
return config;
},
function(error) {
// Do something with request error
return Promise.reject(error);
}
);
服務(wù)端處理前端發(fā)送過來的Token
前端發(fā)送請(qǐng)求攜帶token,后端需要判斷以下幾點(diǎn):
token是否正確,不正確則返回錯(cuò)誤
token是否過期,過期則刷新token 或返回401表示需要從新登錄
關(guān)于上面兩點(diǎn),需要在后端寫一個(gè)中間件來完成:
app.use((ctx, next) => {
if (ctx.header && ctx.header.authorization) {
const parts = ctx.header.authorization.split(' ');
if (parts.length === 2) {
//取出token
const scheme = parts[0];
const token = parts[1];
if (/^Bearer$/i.test(scheme)) {
try {
//jwt.verify方法驗(yàn)證token是否有效
jwt.verify(token, secret.sign, {
complete: true
});
} catch (error) {
//token過期 生成新的token
const newToken = getToken(user);
//將新token放入Authorization中返回給前端
ctx.res.setHeader('Authorization', newToken);
}
}
}
}
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;
}});
});
上面中間件是需要驗(yàn)證token時(shí)都需要走這里,可以理解為攔截器,在這個(gè)攔截器中處理判斷token是否正確及是否過期,并作出相應(yīng)處理。
后端刷新token 前端需要更新token
后端更換新token后,前端也需要獲取新token 這樣請(qǐng)求才不會(huì)報(bào)錯(cuò)。
由于后端更新的token是在響應(yīng)頭里,所以前端需要在響應(yīng)攔截器中獲取新token。
依然以axios為例:
//響應(yīng)攔截器
axios.interceptors.response.use(function(response) {
//獲取更新的token
const { authorization } = response.headers;
//如果token存在則存在localStorage
authorization && localStorage.setItem('tokenName', authorization);
return response;
},
function(error) {
if (error.response) {
const { status } = error.response;
//如果401或405則到登錄頁
if (status == 401 || status == 405) {
history.push('/login');
}
}
return Promise.reject(error);
}
);
總結(jié)
以上所述是小編給大家介紹的koa+jwt實(shí)現(xiàn)token驗(yàn)證與刷新功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Nodejs文件上傳、監(jiān)聽上傳進(jìn)度的代碼
這篇文章主要介紹了Nodejs文件上傳、監(jiān)聽上傳進(jìn)度,本文通過實(shí)例代碼給大家詳細(xì)介紹,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
在Node.js中使用Swagger自動(dòng)生成API接口文檔
這篇文章主要給大家介紹了如何在Node.js項(xiàng)目中使用 Swagger 來自動(dòng)生成 API接口文檔,使用生成方式有很多種,本文基于swagger-jsdoc+swagger-ui-express快速實(shí)現(xiàn),文中通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
Node.js使用officecrypto-tool實(shí)現(xiàn)讀取加密的Excel和Word文檔
這篇文章主要為大家詳細(xì)介紹了Node.js如何使用officecrypto-tool實(shí)現(xiàn)讀取加密的Excel和Word文檔的功能,感興趣的小伙伴可以跟隨小編一起了解一下2023-09-09
詳解nodejs微信公眾號(hào)開發(fā)——2.自動(dòng)回復(fù)
這篇文章主要介紹了詳解nodejs微信公眾號(hào)開發(fā)——2.自動(dòng)回復(fù),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-04-04
express框架實(shí)現(xiàn)基于Websocket建立的簡(jiǎn)易聊天室
本篇文章主要介紹了express框架實(shí)現(xiàn)基于Websocket建立的簡(jiǎn)易聊天室,具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08

