jwt 即 json web token,用户名、密码传入后台后,服务器验证用户数身份以后返回一个json对象
{
username:'lynn',
role:'boss',
expire:'2019-09-09 12:00'
}
jwt token 分为jwt头,有效载荷,签名三个部分,
jwt头是一个描述jwt元数据的json对象,用base64url算法转换为一个字符串
有效载荷包含需要传递的数据信息,可以添加自定义字段,也是一个json数据对象,base64url算法转换为字符串
签名是对前两部分数据的数据签名,通过某种某种算法生成hash值,确保数据不会被篡改
在前端范畴,不需要自己实现生成token,接口获取验证后的token字符串即可,主要是怎样实现身份验证拦截:
登陆验证就是说,在进入某些需要用户登陆或者用户身份的页面,需要先判断用户是否登陆,若已登陆就跳转否则跳转登陆页面,一般配合路由跳转及请求判断code状态完成
⚠️方法一:在每次路由跳转前进行拦截,判断跳转to页面是否需要用户身份,不需要则跳转,需要则继续判断是否登陆(身份是否有效),已登陆则跳转,否则跳转登陆页面
// 路由跳转的时候进行拦截 main.js加入如下代码
router.beforeEach(async (to,from,next) => {
// 判断要去的页面是否需要登陆,如果需要,进行登陆验证,不需要则直接跳转
if (to.meta.needLogin) {
// 进行登陆验证,判断是否登陆,登陆则跳转,没登陆或登陆失效则跳转登陆页面
console.log('judge login status')
let flag =await getState('/state'
flag ? next() : next({name:'Login'})
}else {
next()
}
})
方法二:在封装api的时候添加响应拦截,如果code状态码表示身份无效或未登陆,直接跳转登陆页面
import axios from 'axios'
import routerfrom '@/router/index'
const http =axios.create({
baseURL: process.env.NODE_ENV ==='development' ?'http://localhost:9090' :'/'
})
http.interceptors.response.use((config) => {
// 如果接口状态码表示未登陆
if (config.data.code ===999) {
router.push({name:'Login'})
}
return config
})
⚠️:vue-router如果出现跳转相同地址报错的问题有两种解决方式
1.重新下载vue-router npm -i [email protected] -S
2.给vue-router的push方法绑定this
import Router from 'vue-router'
const RouterPush = Router.prototype.push
Router.prototype.push = function push(location){
return RouterPush.call(this,location).catch(err => err)
}
附上node搭建的测试服务代码
let express = require('express');
let bodyParser = require('body-parser')
let jwt = require('jsonwebtoken')
let app = express();
app.use('*',(req,res,next)=>{
res.header('access-control-allow-origin','http://localhost:8080')
res.header('access-control-allow-headers','content-Type,authorization')
next();
})
// 如果不使用bodyparser,请求的数据不能被服务端获取
app.use(bodyParser.json())
let data = {
code:0,
msg:'',
data:null
}
let secret = 'lynn'
//node服务端获取不到数据,需要用qs插件处理,(使用bodyParser后解决了问题)
app.post('/login',(req,res)=>{
let {username} = req.body
if(username === 'lynn'){
data.code = 0
data.token = jwt.sign({username:'lynn'},secret,{expiresIn:20})
data.msg = "login success!"
data.data = {username:'lynn'}
res.send(data)
}else{
data.code = 1
data.msg = "not find the user, please try again!"
data.data = "用户名不存在"
res.send(data)
}
})
app.get('/state',(req,res) => {
let token = req.headers.authorization;
jwt.verify(token,secret,(err,decode) => {
if(err){
data.code = 1;
data.data = "token 失效了"
}else{
data.code = 0
data.username = decode.username
data.token = jwt.sign({username:'lynn'},secret,{expiresIn:20})
}
res.send(data)
})
})
app.listen('9090',()=>{
console.log('服务器开启咯!')
})