什么是token?
token是一个用户自定义的任意字符串,目前开发中,token都是在服务端生成并且token的值会保存到服务器后台。只有服务器和客户端知道这个字符串,于是,这个token就成了两者之间的秘钥,它可以让服务器确认请求是来自客户端还是恶意的第三方。
为什么使用token?
简单地说,token的使用就是为了数据安全,前台是通过接口路径(URL)的调用来获取数据的,如果恶意的第三方知道了某一个接口路径,那么,他便可以直接通过接口路径在网页上直接获取该接口的所有数据信息。如果添加了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)
})