一、token的引入:
token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,token便应运而生。
二、token的定义:
token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个token便将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。
三、使用token的目的:
简单地说,token的使用就是为了数据安全,前台是通过接口路径(URL)的调用来获取数据的,如果恶意的第三方知道了某一个接口路径,那么,他便可以直接通过接口路径在网页上直接获取该接口的所有数据信息。如果添加了token,类似于这种恶意的行为便不会产生。
token的验证流程:
1.客户端使用用户名跟密码请求登录
2.服务端收到请求,去验证用户名与密码
3.验证成功后,服务端会签发一个 token,再把这个 token 发送给客户端
4.客户端收到 Ttoken 以后可以把它存储起来,比如放在 sessionStorage 里或者 localStorage 里
5.客户端每次向服务端请求资源的时候需要带着服务端签发的 token
6.服务端收到请求,然后去验证客户端请求里面带着的 token,如果验证成功,就向客户端返回请求的数据
axios的[拦截器] :
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
我们可以在 请求之前 和 响应之后 , 添加自定义的逻辑
1.首先我们要存token
// 用户登录
login() {
this.postData = {
account: this.userInfo.account,
password: this.$md5(this.userInfo.password),
};
this.$http.post(configIp.apiConfig.user.login, this.postData)
.then(res => {
if (res.data.meta.status == 200) {
// 保存token
window.localStorage.setItem("token", res.data.data.token);
// 提示
this.$message.success(res.data.meta.msg);
// 跳转
this.$router.push("/index");
} else if (res.data.meta.status == 400) {
// 提示
this.$message.error(res.data.meta.msg);
}).catch(err => {
console.log("登录失败");
})
}
2.接下来 我们用拦截器 在headers统一设置token (因为在之后的接口请求过程中,都要通过token的认证来获取数据)
import axios from 'axios';
import router from './router';
// axios 配置
axios.defaults.timeout = 8000;
axios.defaults.baseURL = 'https://api.github.com';
// http request 拦截器
axios.interceptors.request.use(
config => {
if (localStorage.token) { //判断token是否存在
config.headers.Authorization = localStorage.token; //将token设置成请求头
}
return config;
},
err => {
return Promise.reject(err);
}
);
// http response 拦截器
axios.interceptors.response.use(
response => {
if (response.data.errno === 999) {
router.replace('/');
console.log("token过期");
}
return response;
},
error => {
return Promise.reject(error);
}
);
export default axios;
3.以上操作实现了添加请求头token,在之后的请求中,会自动添加该请求头,但是不是每一个页面都需要登录权限(后台会实现不需要进行token验证的筛选),那么前台也需要通过路由的meta标签对需要做校验的路由页面进行标记,其他页面则不需要验证,代码如下:
路由元信息
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: { requiresAuth: true }
}
]
}
]
})
然后我们就可以在导航守卫中作判断 , 如果meta中的requiresAuth== true ,我们就可以做登录判断 :
// 全局前置守卫(回调函数)
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth == true) {
// 去首页 判断登录
// token
if (window.localStorage.getItem('token') != undefined) {
// 存在就放行
next()
} else {
// new一个实例出来
new Vue().$message.error('滚犊子!!!')
// 不存在
router.push('/login')
}
} else {
// 放过去
next()
}
})
到此就是用 axios的拦截器实现了为请求头统一添加token , 并且实现token的认证 , 还有通过路由元信息 , 实现按需筛选要进行token验证的页面 ..