vue3+axios实现登录拦截 配置axios封装
项目结构├── dist// 打包构建后的文件夹├── node_modules //该项目依赖的模块├── public//存放静态资源(不会变动)├── src│├── assets//存放css、图片与js文件││├── css││├── img││└── js│├── components//存放可复用的小组件│├── http// 封装fetch、post请求及http 拦截器配置.
·
项目结构
├── dist // 打包构建后的文件夹
├── node_modules //该项目依赖的模块
├── public //存放静态资源(不会变动)
├── src
│ ├── assets //存放css、图片与js文件
│ │ ├── css
│ │ ├── img
│ │ └── js
│ ├── components //存放可复用的小组件
│ ├── http // 封装fetch、post请求及http 拦截器配置文件
│ │ ├── api.js
│ │ └── axios.js
│ ├── router //路由配置文件
│ │ └── index.js
│ ├── store //vuex
│ │ └── index.js
│ ├── views //存放主要页面(不可复用的页面组件)
│ ├── App.vue
│ └── main.js
├── .gitignore
├── babel.config.js
├── package-lock.json
├── package.json
├── README.md
└── vue.config.js
登录拦截逻辑
一:路由拦截
首先定义在路由配置文件多添加一个自定义字段requireAuth,用于判断该路由的访问是否需要登录。如果用户已经登录,就顺利进入路由,否则就进入登录页面。
// src/router/index.js
const routes = [
{
path: '/home',
name: '/home',
component: () => import('../views/home/home.vue')
},
{
path: '/user',
name: 'user',
meta: {
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
},
component: () => import('../views/user/user.vue')
},
{
path: '/login',
name: 'login',
component: () => import('../views/login/login.vue')
}
];
vue-router提供的钩子函数beforeEach()
对路由进行判断。
//src/router/index.js
//根据我们的项目需求
router.beforeEach((to,from,next)=>{
if(to.meta.requireAuth){ // 判断该路由是否需要登录权限
if(localStorage.getItem("access_token")) { // 从本地存储localStorage获取当前的token是否存在
next()
}else{
next('/home') //如果token不存在,就跳到首页
}
}else{
if(localStorage.getItem("access_token") && to.path == '/login') { //token存在时候,进去登录页面就自动跳转到首页
next('/home')
}else{
next()
}
}
});
完整的代码,如下:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/home',
name: '/home',
component: () => import('../views/home/home.vue')
},
{
path: '/user',
name: 'user',
meta: {
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
},
component: () => import('../views/user/user.vue')
},
{
path: '/login',
name: 'login',
component: () => import('../views/login/login.vue')
}
];
const router = new VueRouter({
// mode: 'history',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to,from,next)=>{
if(to.meta.requireAuth){ // 判断该路由是否需要登录权限
if(localStorage.getItem("access_token")) { // 从本地存储localStorage获取当前的token是否存在
next()
}else{
next('/home') //如果token不存在,就跳到首页
}
}else{
if(localStorage.getItem("access_token") && to.path == '/login') { //token存在时候,进去登录页面就自动跳转到首页
next('/home')
}else{
next()
}
}
});
export default router
二:拦截器
使用axios的拦截器,统一处理所有http请求和响应。根据我们的项目需求,配合后台接口返回账号被迫下线或者返回401 Unauthorized(未授权),让用户重新登陆。
// src/http/axios.js
import axios from 'axios'
import { Modal, message } from 'ant-design-vue'
import router from '@/router'
axios.defaults.timeout = 10000 // 请求超时时间
const Service = axios.create({
baseURL: '/',
})
// axios 请求拦截器
Service.interceptors.request.use(
config=>{
if(localStorage.getItem("access_token")){
config.headers.Authorization = 'Bearer' + ' ' + localStorage.getItem('access_token');
}
return config
},error=>{
Modal.confirm({
title: '提示',
content: '请求超时!',
});
return Promise.reject(error)
}
)
//有的一个页面请求几个接口,当token过期或者账号被迫下线,避免出现多个弹窗,自定义cont,判断cont==0时候弹窗一次,然后cont++
let cont = 0
// axios respone拦截器
Service.interceptors.response.use(
res=>{
if(res.status == 200){
if(res.data.message && res.data.message.type == 'logout'){
if(cont == 0){
Modal.info({
title: '信息',
content: "你的账号在别处登陆,请注意!",
onOk() {
cont = 0
}
})
localStorage.removeItem('access_token');
localStorage.removeItem('expires_time');
if(router.history.current.path != '/home'){
router.push('/home');
}
}
cont ++;
}
return res;
}else if (res.status == 401){
router.push('/home');
return res;
}else if (res.status == 201) {
return res;
}
return res;
},
error=>{
const responseCode = error.response.status;
switch (responseCode) {
case 400:
message.error('请求错误(400)')
break
case 401:
if(cont == 0) {
message.error('登录过期,请重新登录')
}
cont++
llocalStorage.removeItem('access_token');
localStorage.removeItem('expires_time');
if(router.history.current.path != '/home'){
router.push('/home');
}
break
case 403:
message.error('拒绝访问(403)')
break
case 404:
message.error('请求出错(404)')
break
case 408:
message.error('请求超时(408)')
break
case 500:
message.error('服务器错误(500)')
break
case 501:
message.error('服务未实现(501)')
break
case 502:
message.error('网络错误(502)')
break
case 503:
message.error('服务不可用(503)')
break
case 504:
message.error('网络超时(504)')
break
case 505:
message.error('HTTP版本不受支持(505)')
break
default:
Modal.confirm({
title: '提示',
content: `连接出错(${error.response.status})!`,
});
}
return Promise.reject(error.response.data)
}
)
export default Service;
调用接口
// src/http/api.js
import Service from './axios.js'
// 登录
export const loginApi = data => {
return Service({
url: '/api/authorizations',
method: 'post',
data
})
};
// 用户信息
export const userApi = data => {
return Service({
url: '/api/user' + data,
method: 'get',
})
}
登出
很简单,只需要从本地存储localStorage中当前token清除,再跳转到首页即可。
本文章根据我们的项目需求,作为个人思路笔记,仅供参考。
更多推荐
已为社区贡献3条内容
所有评论(0)