## 4. 权限管理
> 参考链接:
>
> json web token入门教程 http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
>
> jwt官网 https://jwt.io/
### 4.1 token验证
我们通过jwt进行用户认证,jwt的原理是:服务器认证以后,生成一个json对象,发回给用户.
```js
{
"id":"001",
"姓名":"小明",
"角色":"管理员",
"到期时间":"2019年3月3日12时30分"
}
```
以后用户与服务端通信的时候,都要发回这个json对象。服务器完全靠这个对象认定用户身份(一般是通过这个对象的中id去数据库请求数据)。为了防止用户篡改数据,服务器会在生成这个对象的时候,加上签名。就像这种形式:
`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`
关于JWT保存更新的业务流程如下:
1. 保存:登录后保存token
2. 添加:每次发送请求之前检查token是否存在,存在,添加到请求头中,发送请求
3. 更新:每次发送请求服务器返回数据之后更新token
主要逻辑包括:
1. 登录之后,在`localStorage`中保存token
2. 每次发送请求之前,使用axios请求拦截器将token放到请求头中
3. 每次发送请求服务器返回数据之后在axios的响应拦截器中更新token
```js
//1.登录之后保存token login.vue
async login(){
const data = await LOGIN({ name: this.user,pass: this.pass })
//保存token
localStorage.setItem('token',data.token)
//查看是否保存成功
console.log(localStorage.getItem('token'))
}
```
```js
//每次发送请求之前,讲token放到请求头中 api/http.js
//---使用axios的请求拦截器,每次发送请求之前拦截一下
instance.interceptors.request.use(function (config) {
// 给头添加token
if (localStorage.getItem('token')){//存在token,加入头
config.headers.authorization=localStorage.getItem('token')
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
//完成之后,记得发送一个请求,看看是否正确添加token
//---响应拦截器,服务器响应后先到达这里
instance.interceptors.response.use(function (response) {
if(response.data.code=='2000'){//成功响应,更新token
if(response.data.token){
localStorage.setItem('token',response.data.token)
}
}else{
//错误处理 根据不同的状态码,进行错误处理
}
return response.data;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
```
### 4.2 对页面的访问权限
除了对token的操作,我们还要判断用户有没有权限访问这个页面(有些页面是用户必须登录才能访问的),具体配置要使用Vue Router的导航守卫
> 参考链接:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html
在全局前置守卫中进行验证
```js
//在router/index.js进行配置
//在每次进行路由跳转之前进行
router.beforeEach((to,from,next)=>{//增加登录验证
const isLogin=localStorage.getItem('token')?true:false;
if(to.path=='/login'){//如果是登录页面,不需要token
next();
}else{//如果不是登录页面就要判断是否登录
isLogin?next():next('/login');
}
})
```