- 前端发送用户名、密码和验证码到后端
- 后端验证,通过时候就会将token返回给前端
- 前端接收到token后,存储在localStorage和vuex中
- 前端每次跳转路由就去判断下localStorage中有无token,没有就跳转到登陆页面
- 前端每次在向后端发送请求时候都在请求头中加上token
- 携带oken的请求发送到后端,后端进行验证,成功返回数据,如果token过期,返回401
- 前端接收到401时候,提示登录过期,跳转到登录页面,并将存储的token进行清除。
1、在登录成功后将token存在在localStorage中
let params = {
"account": this.addAndEditFormData.account,
"password": this.addAndEditFormData.password,
"verification": this.addAndEditFormData.verification
};
this.api.postApi('/login', params).then(e => {
if (e.data.code === 200) {
localStorage.setItem('Authorization', e.data.data.authorization); // 登录成功后将token存储在localStorage中
this.$router.push({
path: '/manager',
query: {
username: e.name,
account: e.account
}
});
}
});
localStorage.setItem('Authorization', e.data.data.authorization); // 存储
let token = localStorage.getItem('Authorization'); // 获取存储的值
2、在请求拦截中【api.js】设置请求头带上token
import axios from "axios";
import {Message} from "element-ui";
import router from "./router"
// 1、添加请求拦截器,在请求头中加token
axios.interceptors.request.use(
config => {
if (localStorage.getItem('Authorization')) {
config.headers.Authorization = localStorage.getItem('Authorization');
}
return config;
},
error => {
return Promise.reject(error);
});
// 2、响应拦截器
axios.interceptors.response.use(success => {
if (success.status && success.status === 200) {
if (success.data.success === false) {
success.data.message ? Message.error(success.data.message) : Message.error('操作失败!');
}
if (success.data.success === true && success.data.message !== '') {
Message.success(success.data.message);
}
return success;
}
}, error => {
// 调用失败进入下面判断
let r = null;
if (error && error.response) {
let msg = '';
switch (error.response.data.code) {
case 400:
msg = '错误请求'
break;
case 401:
localStorage.removeItem('Authorization');
msg = '未授权,请重新登录'
r = '/login';
break;
case 403:
msg = '拒绝访问'
break;
case 404:
msg = '请求错误,未找到该资源'
break;
case 405:
msg = '请求方法未允许'
break;
case 408:
msg = '请求超时'
break;
case 500:
if (error.response.data.message !== null) {
msg = error.response.data.message;
} else
msg = '服务器出错!'
break;
case 501:
msg = '服务器无法识别请求方法'
break;
case 502:
msg = '网络错误'
break;
case 503:
msg = '服务不可用'
break;
case 504:
msg = '网络超时'
break;
case 505:
msg = 'http版本不支持该请求'
break;
default:
msg = '未知的错误,请联系管理员!'
}
// 在某些特定情况下跳转页面
if (r !== null) {
router.replace(r).then(r => {
});
}
Message.error({message: msg});
} else {
// 超时处理
if (JSON.stringify(error).includes('timeout')) {
Message.error({message: '服务器响应超时,请刷新当前页'})
} else {
Message.error({message: '未知的错误,请联系管理员!'})
}
}
});
/**
* 封装请求
*/
let base = '';
export const postApi = (url, params) => {
return axios({
method: 'post',
url: `${base}${url}`,
data: params
});
};
// get请求
export const getApi = (url, params) => {
return axios({
method: 'get',
url: `${base}${url}`,
data: params
});
};
// put请求
export const putApi = (url, params) => {
return axios({
method: 'put',
url: `${base}${url}`,
data: params
});
};
// delete请求
export const deleteApi = (url, params) => {
return axios({
method: 'delete',
url: `${base}${url}`,
data: params
});
};
3、在路由文件【router/index.js】中设置导航守卫
import Vue from 'vue'
import Router from 'vue-router'
import login from '../views/login'
import register from '../views/register/register'
import manager from '../views/manager/index'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '', // 访问的地址
redirect:'/login', // 重定向
component: login // 组件名称
},
{
path: '/login',
name: 'login',
component: login
},
{
path: '/register',
name: 'register',
component: register
},
{
path: '/manager',
name: 'manager',
component: manager
}
]
});
// 导航守卫
// 使用 router.beforeEach 注册一个全局前置守卫,判断用户是否登陆
router.beforeEach((to, from, next) => {
if (to.path === '/login') {
next();
} else {
let token = localStorage.getItem('Authorization')
if (token === 'null' || token === '') {
next('/login');
} else {
next();
}
}
});
export default router;
4、在退出登录时候清除localStorage中的token值
this.api.getApi("/logout").then(e => {
if (e.data.code === 200) {
this.$router.push("/login"); // 跳转到登录页面
localStorage.removeItem("Authorization"); // 清除localStorage中的token值
}
});
项目结构