egg-jwt的使用
安裝
npm install egg-jwt --save
配置
// config/config.default.js
config.jwt = {
secret: 'zidingyi', // 自定義 token 的加密條件字元串
};
// config/plugin.js
jwt: {
enable: true,
package: 'egg-jwt',
},
使用
- 生成token
// login.js
const token = ctx.app.jwt.sign({
...ctx.request.body,
}, this.app.config.jwt.secret, {
expiresIn: '600m', // 時間根據自己定,具體可參考jsonwebtoken插件官方說明
});
- 驗證token
驗證token通常會寫一個中間件,在需要驗證的路由里引用中間件即可
'use strict';
module.exports = options => {
return async function jwt(ctx, next) {
// 拿到傳會數據的header 中的token值
const token = ctx.request.header.authorization;
const method = ctx.method.toLowerCase();
// 當前請求時get請求,執行接下來的中間件
if (method === 'get') {
await next();
// 當前token值不存在的時候
} else if (!token) {
if (ctx.path === '/api/v1/register' || ctx.path === '/api/v1/login/account') {
await next();
} else {
ctx.throw(401, '未登錄, 請先登錄');
ctx.body = {
code: 50008,
};
}
} else { // 當前token值存在
let decode;
// 解碼token
decode = await ctx.app.jwt.verify(token, options.secret, (err, decoded) => {
if (err) {
if (err.name === 'TokenExpiredError') { // token過期
return 'TokenExpiredError';
} else if (err.name === 'JsonWebTokenError') { // 無效的token
return 'JsonWebTokenError';
}
} else {
return decoded;
}
});
if (decode === 'TokenExpiredError') {
ctx.body = {
code: 401,
msg: '登錄過期,請重新登錄',
};
return;
}
if (decode === 'JsonWebTokenError') {
ctx.body = {
code: 50012,
msg: 'token無效,請重新登錄',
};
return;
}
await next();
}
};
};
- 使用中間件鑒權
// router.js
const jwt = app.middleware.jwt(app.config.jwt);
router.post('/getHousePropertyFee', jwt, controller.getHousePropertyFee.index);
前端處理
- 獲取token
login登錄成功後,後台會把token發送給前端,前端可以將token快取至cookie中。
- 發送token
封裝axios,每次請求去cookie中拿token,並根據後端返回的狀態碼給予用戶提示,比如:token已過期等。。。
// 封裝axios請求
service.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['authorization'] = getToken()
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
// axios 攔截錯誤碼
if (res.code === 50016) {
MessageBox.confirm(res.msg, '提示', {
showClose: false,
showCancelButton: false,
closeOnClickModal: false,
closeOnPressEscape: false,
confirmButtonText: '確定',
type: 'warning'
})
}