5 登录验证及权限设置
既然要做一个系统,肯定就少不了登录验证,我们先实现一个简单的登录页面。首先在components文件夹下新建一个Login.vue文件。
页面相关
首先是html和css部分,script稍后再做介绍。
<template>
<div class="base-background">
<div class="outer">
<div class="login-box">
<el-form :label-position="labelPosition" label-width="auto">
<el-form-item label>
<el-input v-model="username" clearable>
<template slot="prepend">账号</template>
</el-input>
</el-form-item>
<el-form-item label>
<center>
<el-input v-model="password" show-password clearable>
<template slot="prepend">密码</template>
</el-input>
</center>
</el-form-item>
<center>
<el-button class="primary" round @click="login">登录</el-button>
</center>
</el-form>
</div>
</div>
</div>
</template>
<style scoped>
.base-background {
position: absolute;
height: 100%;
width: 100%;
background-color: rgb(165, 219, 245);
}
.outer {
border: 1px;
width: 400px;
height: 300px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: transparent;
}
.login-box {
text-align: center;
vertical-align: middle;
margin-top: 80px;
height: 100%;
width: 100%;
}
</style>
由于自己还没有系统的学习css,所以比较丑= =。然后在路由中添加相关信息(和根路由'/'同级):
{
path: '/Login',
name:'login',
component:() =>import('@/components/Login.vue')
}
直接访问 http://localhost:8080/Login ,效果如下:
现在要做的就是将用户名和密码传输到后端,通过服务器进行验证,这个过程中会使用到axios。
axios
axios是一个易用、简洁且高效的http库,简单理解为一款发送http请求的工具即可。
首先进行安装:
npm install axios
然后在main.ts中引入:
import axios from 'axios'
然后再添加相应的配置:
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
// 为get和post方法分别添加头信息
axios.defaults.headers.get['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
axios.defaults.withCredentials = true
// 需要访问的api的ip地址
axios.defaults.baseURL = 'http://192.168.32.42:8000'
// 设置请求时的拦截器,即在请求前在Authorization字段中写入token
axios.interceptors.request.use(
config => {
if (sessionStorage.token) {
config.headers.Authorization = `${sessionStorage.token}`;
}
return config;
},
err => {
return Promise.reject(err);
}
)
// 设置响应时的拦截器,如果http状态码是401或者404则说明请求异常,清空token并返回到登录页面
axios.interceptors.response.use(
response => {
return response;
},
error => {
if (error.response) {
switch (error.response.status) {
case 401:
sessionStorage.token = "";
router.replace({
path: '/Login',
query: { redirect: router.currentRoute.fullPath }
});
break;
case 404:
sessionStorage.token = "";
router.replace({
path: '/Login',
query: { redirect: router.currentRoute.fullPath }
});
break;
}
}
return Promise.reject(error.response)
}
);
然后将axios注册为全局变量(该语句一定要用在实例化Vue后边):
Vue.prototype.$http = axios
我们再考虑一下Login.vue组件中的登录逻辑,主要逻辑如下所示,对应的注释也给了出来:
<script>
import qs from 'qs';
export default {
data() {
// 一些数据的初始化
return {
labelPosition: "center",
username: "",
password: ""
};
},
methods: {
login() {
let url = "/api/login";
// 访问对应的后端的api获取登录信息
this.$http.post(
url,
qs.stringify({ user: this.username, password: this.password })
).then(response => {
console.log(response.data.token);
// 将获取的数据给予相应的字段,主要是用户名,权限和认证token
sessionStorage.token = response.data.token;
sessionStorage.level = response.data.level;
sessionStorage.user = response.data.username;
console.log(sessionStorage.user)
// 登录成功则跳转到根路由处
this.$router.push('/')
}).catch((err) => {
console.log('登录失败!!!')
this.$message.error('登录失败!!!');
});
}
}
}
</script>
这里看到还需要一个qs模块,我们安装即可:
npm install qs
然后我们开启后端服务器(后端用的是python的flask框架,有机会会详细介绍),输入账号密码,这个账号密码当然是你自己注册并存放在数据库中的。进行登录测试:
至此我们就成功的完成了一个登陆模块。
权限设置
开发过程中肯定也要考虑安全问题,比如有的页面需要对应的用户权限才能访问,没有登录则无法访问。
在vue中可以通过在路由元信息中添加认证设置,从而实现权限控制。
比如我们在/2的路由下的元信息中添加认证字段:
{
path: '2',
name: '2',
// 懒加载
component: () => import('@/components/Content.vue'),
meta: {
title: '2',
requireAuth: true
}
}
当然,要使权限设置生效,我们还需要添加一个路由守卫,在每次路由跳转前验证该页面是否需要验证,将如下的代码添加至router.ts中:
router.beforeEach((to, from, next) => {
let token = sessionStorage.token;//从sessionstorage中获取,或者利用localstorage和vuex
let level = sessionStorage.level;
if (to.meta.requireAuth) { //如果该路由需要登录
if (token) { //且token是存在的,则可以进入该路由
next()
} else {
next({
path: '/Login', //否则跳转到登录页面,
query: { redirect: to.fullPath }//将跳转的路由path作为参数,登录成功后跳转到该路由
})
}
} else {
next()
}
});
然后我们来进行测试,看看效果如何:
不登录直接访问根路由是可以的,因为我们没有添加认证设置。我们再来看看访问/2的效果:
看到跳转到了登录页面,因为我们访问的时候没有token,所以无法访问。因此在进行权限设置时只需要为相应的页面添加认证设置即可。
多页面共享SessionStorage
在实际使用过程中有这么一个使用场景,用户访问一个网站时要打开多个标签页。这个时候问题就来了,我们肯定不能让用户多次登录啊,可通过设置共享SessionStorage来实现。具体SessionStorage,localStorage,Cookie的区别可参考:https://jerryzou.com/posts/cookie-and-web-storage/
下面直接上实现方法,在router.ts中添加如下代码:
(function () {
if (!sessionStorage.length) {
// 这个调用能触发目标事件,从而达到共享数据的目的
localStorage.setItem('getSessionStorage', Date.now().toString());
}
// 该事件是核心
window.addEventListener('storage', function (event) {
if (event.key == 'getSessionStorage') {
// 已存在的标签页会收到这个事件
localStorage.setItem('sessionStorage', JSON.stringify(sessionStorage));
localStorage.removeItem('sessionStorage');
} else if (event.key == 'sessionStorage' && !sessionStorage.length) {
// 新开启的标签页会收到这个事件
if (event.newValue) {
var data = JSON.parse(event.newValue),
value;
for (var key in data) {
sessionStorage.setItem(key, data[key]);
}
}
}
});
})();
同样地,我们来看看实际效果。首先先进行登录操作,为了保证我们处于登录状态,我们访问/2路由:
然后我们再打开一个新的标签页,不进行登录操作,看看是否能直接访问/2:
这说明SessionStorage共享成功。
登录模块就先介绍到这里,后边会带来其他的介绍。