前言
登录模块基本是每个系统都具备的,而且最近刚赶完项目,故将项目中登录模块流程和所遇到的问题进行梳理解决。
技术栈
项目为单页应用默认 hash 模式,采用vue+vue-router+vuex+axios进行功能开发
拦截思路
采用vue-router,axios进行前端登录权限拦截。主要在路由和发起http请求时进行拦截判断
路由拦截
定义路由时,在路由配置中使用meta字段,添加requireAuth字段用于判断路由是否需要登录判断
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: { requireAuth: true }
}
]
}
]
})
复制代码
在vue-router使用 router.beforeEach 注册一个全局前置守卫,在导航守卫中检查元信息字段
const router = new VueRouter(RouterConfig);
// 注册全局钩子用来拦截导航
router.beforeEach((to, from, next) => {
// 当路由切换时,中断当前取消请求
// http.ancelAjax();
let token = Cookies.get('TXKSID');//项目中后端同事采用cookie设置登录状态
if (to.meta.requiresAuth) {// 判断该路由是否需要登录权限
if (token) {//判断登录是否过期
next();
}
} else {//登录失效,则清除登录状态并跳转至登录页面,将跳转的路由path作为参数,登录成功后跳转到该路由
store.dispatch('accountStore/clearLogin');
next({
path: '/login',
query: {redirect: to.fullPath}
})
}
} else {
next()
}
});
复制代码
请求拦截器
项目中在axios库进行封装,以便能统一处理请求和响应
//因为项目中采用cookie,浏览器每次请求会自动带上,因此不需要额外设置
//const TOKEN = Cookies.get('token');
//axios.defaults.headers.common['Authorization'] = TOKEN;
axios.interceptors.request.use(config => {
return config
}, error => {
return Promise.reject(error)
});
axios.interceptors.response.use(res => {
return checkStatus(res);//根据返回状态执行不同操作
}, error => {
if (error.response) {
switch (error.response.status) {
case 500://项目默认接口500则为用户未授权
// 500 清除login信息并跳转到登录页面
store.dispatch('accountStore/clearLogin');
// 只有在当前路由不是登录页面才跳转
router.currentRoute.path !== '/login' &&
router.replace({
path: '/login',
query: { redirect: router.currentRoute.path },
})
case 403:
return error.response
}
}
return Promise.resolve(error.res)
});
复制代码
tips:用户登录过期时,当页面进行刷新,假如当前页有多个请求接口,那么拦截器会多次跳转到登录页,会影响登录之后的路由跳转。所以需要在跳转登录时进行判断。
登录
登录页面只需收集用户账号密码,请求接口登录将用户信息存储到vuex和localStorage,并设置好登录状态就可以。
this.toLogin(loginBody).then((res) => {
if (res.code === '0000') {//请求成功
let redirectUrl = this.$route.query.redirect || this.index;
this.$router.push({
path: redirectUrl
});
});
} else {
this.$toast(res.data || res.message)
}
});
复制代码
通过路由与请求拦截,就可以在前端实现登录拦截。当登出时请求后端登出接口,并清除登录相关信息即可。 至此,登录模块完成,任何意见和建议欢迎提出。