K8s 管理系统项目[前端部分–登录和登出]

1. 登录登出流程

1.1 登录流程

登入流程总的分为5步:

  1. 账号密码验证
  2. token生成
  3. token验证
  4. 验证成功进行跳转
  5. 验证失败返回/login

请添加图片描述

1.2 登出流程

登出流程就相对简单,分为2步

  1. 删除Token
  2. 跳转/login

请添加图片描述

2. 登录代码

src/views/login/Login.vue

这个页面纠结了很久,主要是因为vue-cli从4到5后polyfills不再被包含造成一系报错.不得不放弃jwt改用md5实现.
还有个就是加密的话,如果jwt可以用加盐的方式进行加密.
md5原生只能通过特定的进行加密并比较.想了下单纯用用户名做token的md5加密每次进去都会是一样的.需要手工加个盐,那么就把登录时间作为盐,进行加密和验证.
当然这里只是个演示环境用的方法太简单了.生产中肯定不会这么用.或者小伙伴有更好的方法也请留言.

另外这里为了美观,添加了一个图片,如果不喜欢可以注释掉98行

<template>
  <div class="login">
    <!-- 用户登录卡片 -->
    <el-card class="login-card">
      <template #header>
        <div class="login-card-header">
          <span>用户登录</span>
        </div>
      </template>
      <!-- 表单 -->
      <el-form :model="loginData" :rules="loginDataRules" ref="loginData">
        <el-form-item prop="username">
          <!-- 用户名 -->
          <el-input prefix-icon="UserFilled" v-model.trim="loginData.username" maxlength="32" placeholder="请输入账号" clearable></el-input>
        </el-form-item>
        <el-form-item prop="password">
          <!-- 密码 -->
          <el-input prefix-icon="Lock" v-model.trim="loginData.password" maxlength="16" show-password placeholder="请输入密码" clearable></el-input>
        </el-form-item>
        <el-form-item>
          <!-- 登录按钮 -->
          <el-button type="primary" style="width: 100%;border-radius: 2px" :loading="loginLoading" @click="handleLogin">登 录</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script>
import common from "../common/Config";
import httpClient from '../../utils/request';
import moment from 'moment';
import md5 from 'md5';

export default{
  data() {
    return {
      //加载等待动画
      loginLoading: false,
      //登录验证的后端接口
      loginUrl: common.loginAuth,
      loginData: {
        username: '',
        password: ''
      },
      //校验规则
      loginDataRules: {
        username: [{
          required: true,
          message: '请填写用户名',
          trigger: 'change'
        }],
        password: [{
          required: true,
          message: '请填写密码',
          trigger: 'change'
        }],
      }
    }
  },
  methods: {
    //登录方法
    handleLogin() {
      httpClient.post(this.loginUrl, this.loginData)
          .then(res => {
            //账号密码校验成功后的一系列操作
            localStorage.setItem('username', this.loginData.username);
            localStorage.setItem('loginDate', moment().format('YYYY-MM-DD_HH:mm:ss'));
            const salt = localStorage.getItem('username')+localStorage.getItem('loginDate')
            //生成token
            const tokenExpireTime = new Date(Date.now() + 24 * 60 * 60 * 1000); // 过期时间,24小时后
            // const token = jwt.sign(this.loginData.username, 'test', options);
            const token = md5(salt);
            localStorage.setItem('token', token); // 将Token保存到localStorage中
            localStorage.setItem('tokenExpireTime', tokenExpireTime.getTime().toString()); // 将过期时间保存到localStorage中
            //跳转至根路径
            this.$router.push('/');
            this.$message.success({
              message: res.msg
            })
          })
          .catch(res => {
            this.$message.error({
              message: res.msg
            })
          })
    }
  }
}
</script>

<style scoped>
.login {
  position: absolute;
  width: 100%;
  height: 100%;
  background: aquamarine;
  background-image: url(../../assets/img/login.png);
  background-size: 100%;
}
.login-card {
  position: absolute;
  left: 70%;
  top: 15%;
  width: 350px;
  border-radius: 5px;
  background: rgb(255, 255, 255);
  overflow: hidden;
}
.login-card-header {
  text-align: center;
}
</style>

3. 登录页路由

2.1 login页面

src/router/index.js

    {
        path: '/login',  //url路径
        component: () => import('@/views/login/Login.vue'),  //视图组件
        meta: {title: "登录", requireAuth: false},  //meta元信息
    }

2.2 拦截器

这里去验证是否有token和token是否过期.如果过期了就跳转到/login页面

// 导入md5
import md5 from 'md5';
//路由守卫,路由拦截
router.beforeEach((to, from, next) => {
    //启动进度条
    NProgress.start()
    //设置头部
    if (to.meta.title) {
        document.title = to.meta.title
    } else {
        document.title = "Kubernetes"
    }
    // 放行
    if (window.location.pathname == '/login') {
        next()
    }else{
        // 获取localStorage中保存的Token和过期时间
        const storedToken = localStorage.getItem('token');
        const storedTokenExpireTime = localStorage.getItem('tokenExpireTime');
        // 如果没有保存Token或过期时间,或者Token已经过期,则跳转到登录页面

        if (!storedToken || !storedTokenExpireTime || Date.now() > parseInt(storedTokenExpireTime)) {
            // 删除localStorage中保存的Token和过期时间
            localStorage.removeItem('token');
            localStorage.removeItem('tokenExpireTime');

            // 如果当前不在登录页面,则跳转到登录页面
            if (window.location.pathname !== '/login') {
                window.location.href = '/login';
            }
        } else {
            // 验证Token是否正确
            const salt = localStorage.getItem('username')+localStorage.getItem('loginDate')
            const token = md5(salt); // 使用md5算法生成Token

            if (token === storedToken) {
                // Token正确,且在有效期内,继续进行其他操作
                // TODO: 继续访问
                next()
            } else {
                // Token错误,跳转到登录页面
                localStorage.removeItem('token');
                localStorage.removeItem('tokenExpireTime');

                // 如果当前不在登录页面,则跳转到登录页面
                if (window.location.pathname !== '/login') {
                    window.location.href = '/login';
                }
            }
        }
    }
})

4. 登出代码

src/layout/Layout.vue

这部分还是比较简单的.其实和路由守卫判断token失效是一样的

<script>
	//登出
    logout() {
      //移除用户名
      localStorage.removeItem('username');
      //移除token
      localStorage.removeItem('token');
      //跳转至/login页面
      this.$router.push('/login');
    }
</script>

5. 效果

登录页

请添加图片描述

清理掉本地存储进行登录

请添加图片描述

密码验证成功后会生成username,loginDate,token,tokenExpireTime这4个键值对

其中username存放用户名,loginDate存放登录时间(用于产生过期时间和作为md5运算的盐),token存放md5加密后的token,tokenExpireTime存放token过期时间.

请添加图片描述

此时进行不同页面切换,可以正常访问

请添加图片描述

如果修改username,loginDate,token则会因为token验证失败跳转到登录页面

请添加图片描述

再访问其他任意页面就调回了/login页面并清理掉了token和tokenExpireTime

请添加图片描述

调小tokenExpireTime值一样(将值由1677733016817改为1627733016817)

请添加图片描述

一样会清理掉token和tokenExpireTime并跳转/login

请添加图片描述
至此,整个前后端的开发已经完成.下面进入环境部署环节

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐