人力资源管理后台 === 登陆+主页灵鉴权

news2024/11/28 7:26:19

目录

1. 分析登录流程

2. Vuex中用户模块的实现

3.Vue-cli代理解决跨域

4.axios封装

5.环境区分

6. 登录联调

7.主页权限验证-鉴权


1. 分析登录流程

image.png

传统思路都是登录校验通过之后,直接调用接口,获取token之后,跳转到主页。

  • vue-element-admin的登录思路:
  1. 登录表单校验通过
  2. 调用Vuex提供的登录的action
  3. 登录的Action中会调用接口
  4. 登录接口如果成功执行,会返回token
  5. 利用Vuex的特性,将token共享的到Vuex中,这样Vuex就统一管理了token,别的地方想要使用,直接通过Vuex就可以
  6. 登录接口会调用单独封装的请求模块(api)
  7. 请求模块中又会使用用到axios封装的请求工具
  8. 而请求工具又要考虑区分 开发环境和生产环境的问题
  9. 请求时还要考虑前后分离项目产生的跨域问题,要使用代理解决跨域

2. Vuex中用户模块的实现

登录流程中最核心的是用户模块,所以这部分我们单独拿出来进行重写。

代码位置(src/store/modules/user.js)

  • 删除原有模板中用户模块中的内容
  • 导出Vuex子模块-声明一个状态token
const state = {
  token: null
}
const mutations = {}
const actions = {}
export default {
   namespaced: true,
   state,
   mutations,
   actions
}
  • 实现token的Vue数据持久化
import { getToken, setToken, removeToken } from '@/utils/auth'
const state = {
  token: getToken(), // 从缓存中读取初始值
}
const mutations = {
  setToken(state, token) {
    state.token = token
    // 同步到缓存
    setToken(token)
  },
  removeToken(state) {
    // 删除Vuex的token
    state.token = null
    removeToken()
  }
}
export default {
  namespaced: true, // 开启命名空间
  state,
  mutations,
  actions
}

  • 实现登录的action方法
const actions = {
  // context上下文,传入参数
  async login(context, data) {
    console.log(data)
    // todo: 调用登录接口
    const token = await login(data)
    // 返回一个token 123456
    context.commit('setToken', token)
  },
}
  • 在登录组件中调用该action方法-代码位置(src/views/login/index.vue)
export default {
  methods: {
    login() {
      this.$refs.form.validate((isOK) => {
        if (isOK) {
          this.$store.dispatch("user/login", this.loginForm)
        }
      })
    }
  }
}

注意: 因为user模块导出的时候namespaced为true,所以我们调用action的时候要加上模块名称如user/login

3.Vue-cli代理解决跨域

上个小节,完成了Vuex用户模块的创建和持久化管理,现在已经调通了 **登录页面- action,**继续往下需要处理
请求模块-axios封装-跨域-区分环境

image.png

我们要先把跨域问题解决才能考虑其他内容的开发

  • 首先为什么会有跨域?

image.png

在后端没有开启cors的情况下,浏览器的同源策略会直接限制后端返回的数据给到前端。这是因为我们目前所有的项目都是前后分离,前端一个服务, 后端一个服务,后端不开cors只能前端自己想办法。

  • 代理是怎么解决跨域的?

image.png

既然前端不能直接请求后端服务,那就搞个中间服务,中间服务刚好和我们的前端服务同源,前端和中间服务可以通信,而中间服务是node, node后台向后端发请求是不受同源策略影响的,因为同源策略只针对浏览器!!!, 这样就是代理,中间层的服务将前端的请求代理给了后端接口。

  • 具体怎么做呢?

跨域有开发环境跨域和生产环境跨域,我们最后上线的时候要考虑生产环境跨域,目前只需要考虑开发环境。

  • 配置文件可以直接配置代理 vue.config.js
  devServer: {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    proxy: {
      '/api': {
        target: 'https://heimahr.itheima.net'
      }
    }
    // before: require('./mock/mock-server.js')
  },

注意: 要去掉before这个选项,这个是mock数据,会影响到我们的请求,并且修改完成之后要重启服务。

4.axios封装

完成了代理跨域,就可以考虑axios的封装了。

image.png

axios封装主要封装做哪些呢?

  • 基础地址,超时时间
  • 请求拦截器-统一注入token
  • 响应拦截器-解构数据-处理异常

image.png

  • axios的基础功能

image.png

代码位置(src/utils/request.js)

import axios from 'axios'
import store from '@/store'
const service = axios.create({
  baseURL: '/api',
  timeout: 10000,
})

service.interceptors.request.use((config) => {
  // 注入token
//  this.$store.getters
  // store.getters.token => 请求头里面
  if (store.getters.token) {
    config.headers.Authorization = `Bearer ${store.getters.token}`
  }
  return config
}, (error) => {
  // 失败执行promise
  return Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use((response) => {
  const { data, message, success } = response.data // 默认json格式
  if (success) {
    return data
  } else {
    Message({ type: 'error', message })
    return Promise.reject(new Error(message))
  }
}, async(error) => {
  // error.message
  Message({ type: 'error', message: error.message })
  return Promise.reject(error)
})

export default service

5.环境区分

image.png


 

image.png

image.png

image.png

  • 将.env.development中的值改为 /api 作为请求工具的基础地址
  • **process.env.VUE_APP_BASE_API **的表示读取该变量,npm run dev时该变量为 /api, npm run build:prod时 该变量为 /prod-api

6. 登录联调

目前登录功能只剩下红色的部分还需要

image.png

  • 首先封装登录的API请求-代码位置(src/api/user.js)
import request from '@/utils/request'

export function login(data) {
  return request({
    url: '/sys/login',
    method: 'post',
    data
  })
}
  • Vuex中的用户模块调用登录接口-代码位置(src/store/modules/user.js)
const actions = {
  // context上下文,传入参数
  async login(context, data) {
    console.log(data)
    // todo: 调用登录接口
    const token = await login(data)
    // 返回一个token 123456
    context.commit('setToken', token)
  }
}
  • 登录成功后,跳转到主页-代码位置(src/views/login/index.vue)
  methods: {
    login() {
      this.$refs.form.validate(async(isOK) => {
        if (isOK) {
          await this.$store.dispatch('user/login', this.loginForm)
          // Vuex 中的action 返回的promise
          // 跳转主页
          this.$router.push('/')
        }
      })
    }
  }
  • 区分不同环境的数据-代码位置(src/views/login/index.vue)

因为开发环境为了便利,我们将用户的账户信息和密码都默认写在了页面上,但是真正的项目我们不可能将数据进行暴露出去,所以在生产环境时应该将 用户的手机号和密码抹去

export default {
  name: 'Login',
  data() {
    return {
      loginForm: {
        mobile: process.env.NODE_ENV === 'development' ? '13800000002' : '',
        password: process.env.NODE_ENV === 'development' ? '123456' : '',
        isAgree: process.env.NODE_ENV === 'development'
      }
    }
  }
}

7.主页权限验证-鉴权

当前项目用户是否有权限访问主页,要考虑当前有没有token, 如果有token, 用户还想去登录页,我们可以直接去主页-这个就是免登录功能。有token的情况下,直接到主页。

image.png

  • 访问主页-有token放过,没有token跳到登录页
  • 访问登录-有token跳到主页,没有token放过

代码实现-代码位置(src/pemission.js)

import router from '@/router'
import nprogress from 'nprogress'
import 'nprogress/nprogress.css'
import store from '@/store'

/**
 *前置守卫
 *
*/

const whiteList = ['/login', '/404']
router.beforeEach(async(to, from, next) => {
  nprogress.start()
  if (store.getters.token) {
    // 存在token
    if (to.path === '/login') {
      // 跳转到主页
      next('/') // 中转到主页
      // next(地址)并没有执行后置守卫
      nprogress.done()
    } else {
       next() // 放行
    }
  } else {
    // 没有token
    if (whiteList.includes(to.path)) {
      next()
    } else {
      next('/login') // 中转到登录页
      nprogress.done()
    }
  }
})

/** *
 * 后置守卫
 * **/
router.afterEach(() => {
  nprogress.done()
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1254396.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一、深入简出串口(USRT)通信——基本概念。

一、前言 串口到底是什么?简单来说一句话就可以解释,串口就是一种通信协议。 看到这里可能大家会觉得你这不是放屁么,说了跟没说一样。所以这里做前言来描述,大家要先对通信协议有一个下意识地认识才能在学习串口的时候不至于迷茫…

使用Pytorch从零开始构建Normalizing Flow

归一化流 (Normalizing Flow) (Rezende & Mohamed,2015)学习可逆映射 f : X → Z f: X \rightarrow Z f:X→Z, 在这里X是我们的数据分布,Z是选定的潜在分布。 归一化流是生成模型家族的一部分,其中包括变分自动编…

PostgreSQL+patroni+etcd+haproxy+keepalived高可用

PostgreSQLpatronietcdhaproxykeepalived 高可用架构 部署环境 部署postgresql-15 一主二从: role主机组件主库 node203 192.168.56.203 pg15.5 Patroni、Etcd,haproxy、keepalived 从库 node204 192.168.56.204 pg15.5 Patroni、Etcd,ha…

Java(七)(Lambda表达式,正则表达式,集合(Collection,Collection的遍历方式))

目录 Lambda表达式 省略写法(要看懂) 正则表达式 语法 案例 正则表达式的搜索替换和分割内容 集合进阶 集合体系结构 Collection Collection的遍历方式 迭代器 增强for循环 Lambda表达式遍历Collection List集合 ArrayList LinkedList 哈希值 HashSet底层原理 …

ArcGIS中基于人口数据计算人口密度的方法

文章目录 一、密度分析原理二、点密度分析三、线密度分析四、核密度分析一、密度分析原理 密度分析是指根据输入的要素数据集计算整个区域的数据聚集状况,从而产生一个联系的密度表面。通过密度计算,将每个采样点的值散步到整个研究区域,并获得输出栅格中每个像元的密度值。…

R语言实现Lasso回归

一、Lasso回归 Lasso 回归(Least Absolute Shrinkage and Selection Operator Regression)是一种用于线性回归和特征选择的统计方法。它在回归问题中加入了L1正则化项,有助于解决多重共线性(多个特征高度相关)和特征选…

Java中有几种基本数据类型以及转换方式【Java面经(1)】

问:Java中有几种基本数据类型呢?以及它们之间的转换方式。详细介绍下 总共有8种基本数据类型 byte 、short 、long 、float 、double 、boolean 、char 详细类型以及字节数: 基本数据类型的转换方式 自动类型转换:小–>大 byt…

Vue快速实践总结 · 上篇

文章目录 模板语法数据绑定事件处理计算属性监视属性(监听器)条件渲染列表渲染数据监视原理内置指令总结生命周期组件化编程组件使用步骤组件的嵌套this指向单文件组件ref、props 脚手架(Vue CLI)render函数 参考自己的Vue专栏以及Vue官方文档 模板语法 …

stm32 42步进电机 上位机示例

脉冲到底是个啥东西?步进电机一直说发脉冲 步进电机通过接收脉冲信号来实现精确的位置控制。脉冲是一种短暂的电信号,它的变化可以触发步进电机转动一定的角度或步进。步进电机控制系统会根据输入的脉冲信号来精确定位和控制步进电机的转动,每…

Android平台GB28181设备接入模块开发填坑指南

技术背景 为什么要开发Android平台GB28181设备接入模块?这个问题不再赘述,在做Android平台GB28181客户端的时候,媒体数据这块,我们已经有了很好的积累,因为在此之前,我们就开发了非常成熟的RTMP推送、轻量…

rsyslog出现Unit rsyslog.service is masked不可用问题解决

博主在测试将日志发送到日志服务器的功能时遇到了rsyslog服务不可用的问题,具体来说,就是执行systemctl restart rsyslog或者 service rsyslog restart命令时,出现了标题中所述的Unit rsyslog.service is masked问题。网上查找了很多资料&…

云服务器上部署 Web 项目及端口异常处理

文章目录 1. 在云服务器的 MySQL(MariaDB) 中, 建库建表2. 微调代码3. 打包4. 把 war 包 拷贝到云服务器上端口被占用处理 1. 在云服务器的 MySQL(MariaDB) 中, 建库建表 在云服务器中进入 MySQL mysql -u root -p把之前本地写好的 SQL 代码一粘贴即可 例如: -- 这个文件主要…

【Python】用三种方法创建tkinter桌面窗口

Python的tkinter是Python的标准GUI库之一,它是一个开源的、跨平台的GUI工具包,可以用于创建桌面应用程序。 tkinter提供了许多常见的GUI组件,例如按钮、文本框、标签、列表框等等,可以轻松地创建各种类型的桌面应用程序。它还支持…

go atexit源码分析

文章目录 atexit源码解析UML类图样例一: 程序退出之前执行注册函数1.1 流程图1.2 代码分析 样例二:使用cancel取消注册函数2.1 cancel流程图2.2 代码分析 样例三:使用Fatal/Fatalln/Fatal执行注册函数3.1 Fatal/Fatalln/Fatal流程图3.2 代码分析 atexit源…

什么是LASSO回归,怎么看懂LASSO回归的结果

随着机器学习的发展,越来越多SCI文章都使用了更多有趣、高效的统计方法来进行分析,LASSO回归就是其中之一。很多小伙伴听说过LASSO,但是对于LASSO是什么,有什么用,怎么才能实现,大家可能一头雾水。今天的文…

每日一题2023.11.26——个位数统计【PTA】

题目要求: 输入格式: 每个输入包含 1 个测试用例,即一个不超过 1000 位的正整数 N。 输出格式: 对 N 中每一种不同的个位数字,以 D:M 的格式在一行中输出该位数字 D 及其在 N 中出现的次数 M。要求按 D 的升序输出。…

【华为数通HCIP | 网络工程师】821-IGP高频题、易错题之OSPF(7)

个人名片: 🐼作者简介:一名大三在校生,喜欢AI编程🎋 🐻‍❄️个人主页🥇:落798. 🐼个人WeChat:hmmwx53 🕊️系列专栏:🖼️…

blender 3D眼球结构

角膜(Cornea):眼球的前部,透明的曲面,负责折射光线。虹膜(Iris):眼睛的颜色部分,控制瞳孔大小以调整进入眼睛的光量。瞳孔(Pupil):虹膜…

S25FL系列FLASH读写的FPGA实现

文章目录 实现思路具体实现子模块实现top模块 测试Something 实现思路 建议读者先对 S25FL-S 系列 FLASH 进行了解,我之前的博文中有详细介绍。 笔者的芯片具体型号为 S25FL256SAGNFI00,存储容量 256Mb,增强高性能 EHPLC,4KB 与 6…

快速幂算法详解(C++实现)

文章目录 1. 什么是快速幂2. 暴力求解代码实现缺陷分析 3. 优化一:取模运算的性质4. 优化二:快速幂算法的核心思想5. 终极优化:位运算优化6. 源码 这篇文章我们来一起学习一个算法——快速幂算法。 1. 什么是快速幂 顾名思义,快速…