什么是token?
token是一个用户自定义的任意字符串,目前开发中,token都是在服务端生成并且token的值会保存到服务器后台。只有服务器和客户端知道这个字符串,于是,这个token就成了两者之间的秘钥,它可以让服务器确认请求是来自客户端还是恶意的第三方。
为什么使用token?
基于token验证的流程
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名和密码(后台根据请求去数据库查找是否有该用户)
- 验证成功后,服务端会签发一个token(该token值一般都会存入Redis数据库中,并设置过期时间),再把这个token发送给客户端
- 客户端收到token之后,一般存储在localStorage(HTML5新特性,只要不手动删除存储的内容,存储的信息会一直存在)中
- 客户端每次向服务端请求资源的时候需要带着服务端签发的token
- 服务端收到请求,然后去验证客户端请求里面带着的token(token是否为该用户的令牌以及token是否有效等),如果验证成功,就向客户端返回请求的数据
什么是axios?
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
官方网址:www.axios.com/
中文文档:www.kancloud.cn/yunye/axios…
vue实现axios拦截,token验证
在简单介绍完这些基础知识以及用到的插件之后,我们便要开始今天的主题--token验证。
首先在vue.js 中下载axios,npm install axios
,在 main.js
文件中全局使用:
import axios from 'axios';
Vue.prototype.$http = axios;
这样引入之后,在其他的文件中便可以使用$http
来调用接口:
getRoomDetail() {
this.$http.get(this.roomDetailApi).then(
res => {
this.roomDetail = res.data.data;
},
err => {
console.log("接受数据错误" + err);
}
).catch(err => {
console.log("服务器错误" + err);
})
}
以上步骤只是简单的实现了前后台的交互(在前台调用后台接口来获取数据),接下来我们便要进一步学习,实现token的验证。
根据上面的介绍,我们在成功登录后台并拿到返回给的token之后,需要使用localStorage全局存储,实现代码如下:
// 用户登录
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.errno === 0) {
this.$Message.success('登陆成功');
this.$router.push('roomInfo');
//全局存储token
window.localStorage["token"] = JSON.stringify(res.data.data.token);
} else {
this.$Message.error('登录失败');
this.forgetPassword = true;
}
}).catch(err => {
console.log("登录失败");
})
},
接下来,我们要做的就是设置请求头,在之后的接口请求过程中,都要通过token的认证来获取数据,添加 http.js
文件(拦截器)
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;
添加拦截器之后,修改 main.js
文件: 将上面
import axios from 'axios';
Vue.prototype.$http = axios;
改为:
import http from './http'; //此处问http文件的路径
Vue.prototype.$http = http;
完成该步骤之后,基本的操作已经实现了,下面让我们查看一下是否已经添加请求头:
以上操作实现了添加请求头token,在之后的请求中,会自动添加该请求头,但是不是每一个页面都需要登录权限(后台会实现不需要进行token验证的筛选),那么前台也需要通过路由的meta标签对需要做校验的路由页面进行标记,其他页面则不需要验证,代码如下:
{
path: '/userInfo',
name: 'userInfo',
meta: {
requireAuth: true, // 该路由项需要权限校验
}
component: userInfo
}, {
path: '/userList',
name: 'userList', // 该路由项不需要权限校验
component: userInfo
}
之后,我们可以定义一个路由防卫,每次路由跳转,我们都来做一下权限校验,参考代码如下:
router.beforeEach((to, from, next) => {
if (to.meta.requireAuth) { // 判断该路由是否需要登录权限
if (localStorage.token) { // 获取当前的token是否存在
console.log("token存在");
next();
} else {
console.log("token不存在");
next({
path: '/login', // 将跳转的路由path作为参数,登录成功后跳转到该路由
query: {redirect: to.fullPath}
})
}
}
else { // 如果不需要权限校验,直接进入路由界面
next();
}
});
到此,用vue.js实现前台添加请求头,通过axios设置拦截器添加token就已经实现了。
直接添加token
如果不使用拦截器,直接使用axios请求的话,有时候需要在post请求头部添加token,语法为:
let params = {
//请求参数设置
}
axios.post(url,params,{
headers:{
'token':localStorage.getItem("token")
}
}).then(res=>{
console.log('res=>',res)
})
如果是get请求添加token,语法为:
let args = {
//请求参数设置
}
axios.get(url,{
headers:{
'token':localStorage.getItem("token")
},
params:args
}).then(res=>{
console.log('res=>',res)
})