一次简单的Vue项目

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 ,效果如下:

image

现在要做的就是将用户名和密码传输到后端,通过服务器进行验证,这个过程中会使用到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框架,有机会会详细介绍),输入账号密码,这个账号密码当然是你自己注册并存放在数据库中的。进行登录测试:

image

至此我们就成功的完成了一个登陆模块。

权限设置

开发过程中肯定也要考虑安全问题,比如有的页面需要对应的用户权限才能访问,没有登录则无法访问。

在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()
  }
});

然后我们来进行测试,看看效果如何:

image

不登录直接访问根路由是可以的,因为我们没有添加认证设置。我们再来看看访问/2的效果:

image

看到跳转到了登录页面,因为我们访问的时候没有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路由:

image

然后我们再打开一个新的标签页,不进行登录操作,看看是否能直接访问/2:

image

这说明SessionStorage共享成功。

登录模块就先介绍到这里,后边会带来其他的介绍。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容

  • 2 搭建一个简单的后台管理布局 文件创建 在准备好相关环境后,我们开始创建自己的项目。整个项目的目录结构如下图所示...
    Prejudice_ccca阅读 783评论 0 0
  • 3 路由实现 在摸爬滚打一段时间后,决定进行路由相关的处理。 利用导航栏进行路由 本文采用的是element ui...
    Prejudice_ccca阅读 547评论 0 1
  • 4 表格使用 表格是前端经常使用到的一个工具,尤其是在管理系统中,因为存在着数据的展示和操作(增删改查)。 我们将...
    Prejudice_ccca阅读 466评论 0 0
  • 1 环境准备 最近由于项目需要且人员不足(其实是不想求别人。。。),又希望多学点知识,于是动手自己搭建一个后台管理...
    Prejudice_ccca阅读 911评论 0 1
  • element-ui 文档 Vue项目接口文档地址 博客 session 和 cookie等 学什么? 1 如何使...
    cj_jax阅读 3,923评论 0 10