token:服务端生成的一串字符串,可以解决频繁登录的问题
它作为客户端进行请求的一个令牌:
第一次登录后,服务器生成一个token返回给客户端;
客户端只需要带上token来请求数据即可,无需再次带上用户名和密码
为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮
生成token的插件:jsonwebtoken
下载:cnpm install jsonwebtoken --save
引入:
var jwt = require('jsonwebtoken');
var str= "this is a mimi"; //创建token时进行加密的一个依据
function createToken(obj){
obj.time=Date.now(); //时间戳
return token=jwt.sign(obj,str,{expiresln:60*60});
}
function verifyToken(token){
return new Promise((resolve,reject)=>{
jwt.verify(token,str,(err,data)=>{
if(err){
reject(err)
}else{
resolve(data)
}
})
})
}
我们前端对于token的处理主要就是通过cookies第三方插件来设置token和删除token
下载:cnpm install js-cookie --save
引入:import cookies from "js-cookie"
export const setToken=(key,value,tokenExpires)=>{
cookies.set(key,value,{expires:tokenExpires || 1})
}
export const getToken=(key)=>{
return cookies.get(key)
}
export const removeToken=(key)=>{
cookies.remove(key)
}
在登录的时候,引入上面设置token的方法,在验证登录信息通过后,setToken(res.data.token,2)
需要配合后台app.js中的token判断及登录拦截使用
在引入axios的文件request.js中,引入getToken和removeToken的方法
import axios from "axios"
import Setting from "./setting.js";
import { getToken, removeToken } from "./auth.js"
// 引入路由,用于下面的跳转登录
import router from "@/router"
// 创建一个服务
const service = axios.create({
baseURL: Setting.baseUrl,
timeout: 5000
})
// axios的请求拦截机--把token设置到请求头中
service.interceptors.request.use(config => {
let token = getToken();
// console.log(token);
// console.log(config);
if (token) {
config.headers['authorization'] = token
}
return config
}, error => {
return Promise.reject(error)
})
// axios的响应拦截机--主要就是把状态码对应的页面反映出来
service.interceptors.response.use(res => {
// console.log(res);
// 接收判断登录的状态码
let status = res.data.status
// console.log(status);
switch (status) {
case 200:
// 说明登录成功
return res.data;
case 401:
case 1001:
case 1002:
removeToken()
router.replace({ path: '/admin/login' })
break;
default:
break
}
}, error => {
return Promise.reject(error)
})
export default service
import Vue from "vue"
import VueRouter from "vue-router"
import { getToken } from "@/utils/auth.js"
// 引入routes模块
import routes from "./routes"
// 使用路由
Vue.use(VueRouter)
//解决报错Navigation cancelled from “/userIndex“ to “/blank/login“ with a new navigati
const originalPush = VueRouter.prototype.push
const originalReplace = VueRouter.prototype.replace
// push
VueRouter.prototype.push = function push(location, onResolve, onReject) {
if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
return originalPush.call(this, location).catch(err => err)
}
// replace
VueRouter.prototype.replace = function push(location, onResolve, onReject) {
if (onResolve || onReject) return originalReplace.call(this, location, onResolve, onReject)
return originalReplace.call(this, location).catch(err => err)
}
// 实例化一个路由对象
let router = new VueRouter({
routes
})
// 路由守卫--方法一
router.beforeEach((to, from, next) => {
// console.log(from); //前一个路由
// console.log(to); //当前路由
const token = getToken()
// 把登录页面放行,条件是当前路由处于登录页面并且不存在token
if (to.path !== "/admin/login" && !token) next("/admin/login")
next()
// 获取token值
console.log(token);
})
// 路由守卫--方法二
router.beforeEach((to, from, next) => {
// console.log(from); //前一个路由
// console.log(to); //当前路由
if (to.path == "/admin/login") {
next()
return;
}
const token = getToken()
if (!token) return next("/admin/login")
next()
// 把登录页面放行,条件是当前路由处于登录页面并且不存在token
// if (to.path !== "/admin/login" && !token) next("/admin/login")
// next()
// 获取token值
console.log(token);
})
// 暴露出去
export default router