項目架構:vue+node.js
jwt 驗證流程
1、客戶端訪問登陸接口(不帶token),請求服務器驗證
2、服務器驗證通過,通過jwt返回給客戶端一個token
3、客戶端請求其他接口時帶上從服務器獲取的token
4、服務器驗證客戶端的token,驗證通過后,返回給客戶端訪問接口數據
阮一峰 JSON Web Token:
http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
服務端node.js
1、安裝依賴
npm install jsonwebtoken –save
npm install koa-jwt –save
2、中間件請求token
app.use(async (ctx, next) => {
// let token = ctx.header.authorization;
return next().catch((err) => {
if (err.status === 404) {
ctx.status = 404;
ctx.body = {
code: 404,
msg: err.message
}
} else {
throw err;
}
})
});
3、排除不驗證的請求
app.use(koajwt({ secret: secret }).unless({
// 登錄接口不需要驗證
path: [/^\/api\/login/]
}));
4、登陸簽發token
app.use(async (ctx, next) => {
if(ctx.request.method==='POST'&&ctx.request.url==='/api/login'){
const postData = ctx.request.body.user
const {login_name,login_password}=JSON.parse(postData)
//判斷賬號和密碼是否正確
//xxx
//登陸成功返回token
const token=sign({login_name},secret,{expiresIn:'1h'})
ctx.body=token
}else{
//繼續執行api請求
await next()
}
});
/* * @Author: wuyongxian * @Date: 2019-11-04 17:52:58 * @Last Modified by: * @Last Modified time: 2019-11-04 17:53:23 */ const Koa = require('koa'); const app = new Koa(); //jwt token驗證 const { sign } = require('jsonwebtoken'); const secret = 'xxx'; const koajwt = require('koa-jwt'); // 中間件對token進行驗證 app.use(async (ctx, next) => { // let token = ctx.header.authorization; return next().catch((err) => { if (err.status === 404) { ctx.status = 404; ctx.body = { code: 404, msg: err.message } } else { throw err; } }) }); //排除不驗證的請求 app.use(koajwt({ secret: secret }).unless({ // 登錄接口不需要驗證 path: [/^\/api\/login/] })); app.use(async (ctx, next) => { if(ctx.request.method==='POST'&&ctx.request.url==='/api/login'){ const postData = ctx.request.body.user const {login_name,login_password}=JSON.parse(postData) //判斷賬號和密碼是否正確 //xxx //登陸成功返回token const token=sign({login_name},secret,{expiresIn:'1h'}) ctx.body=token }else{ //繼續執行api請求 await next() } }); app.listen(3000);
參考:https://www.jianshu.com/p/663520bd7e95
客戶端vue:
1、登陸驗證獲取token
loginAuth() { let params = { login_name: this.ruleForm.username, login_password: md5(this.ruleForm.password) } let that = this //axios 請求后台接口 api.login(params).then(res => { if (res.code == 0) { that.MSG.success(res.msg) that.loginSuccess(res) } else {//result.state==1||reuslt.state==2 that.MSG.warning(res.msg) } }) }, //登陸成功 loginSuccess(result) { sessionStorage.setItem('token', result.token) this.$router.push({ path: '/index' }) }
獲取到的token可以放到sessionStorage、Vuex.Store獲取其他存儲介質中,方便下次調用接口使用
2、在main.js文件,在請求攔截方法中,為請求接口加入token
需要注意的是token格式為:‘Bearer ’+token,token參數需要賦值給請求頭的Authorization
axios.interceptors.request.use( config => { //除登陸接口意外的接口都要加上token,才可以請求接口 if (!config.url.endsWith('/api/login')) { if(sessionStorage.getItem('token')!=null){ const token='Bearer '+sessionStorage.getItem('token') config.headers.common['Authorization']=token } } return config; }, error => { return Promise.reject(error); } );
請求頭參數格式:

