VUE+SPRINGBOOT从0-1打造前后端-前后台系统-登录实现

在现代Web应用开发中,前后端分离架构已成为主流模式。本文将详细介绍一个基于Vue.js和SpringBoot的前后端分离登录系统的设计与实现,涵盖了前端表单验证、验证码组件、后端权限处理等关键技术点。

一、前端登录页面实现

1.1 页面结构与样式

复制代码
<template>
  <div class="Login-container">
    <div class="allClass">
      <div class="titleClass"><b>欢迎登录人工智能系统</b></div>
      <!-- 表单部分省略 -->
    </div>
  </div>
</template>

<style scoped>
.Login-container {
  height: 100vh;
  background-image: linear-gradient(to bottom right, deepskyblue, darkcyan);
  overflow: hidden;
}
/* 其他样式省略 */
</style>

前端页面采用了Element UI组件库,整体布局简洁美观:

  • 使用全屏渐变背景增强视觉效果

  • 登录框居中显示,采用圆角设计

  • 响应式布局适应不同屏幕尺寸

1.2 表单验证实现

复制代码
data() {
  return {
    ruleList: {
      name: [
        {required: true, message: '请输入用户名即您的邮箱', trigger: 'blur'},
        {min: 3, max: 60, message: '长度在3-60个字符', trigger: 'blur'}
      ],
      password: [
        {required: true, message: '请输入密码', trigger: 'blur'},
        {min: 3, max: 60, message: '长度在3-60个字符', trigger: 'blur'}
      ],
      validCode: [
        {required: true, message: '请输入验证码', trigger: 'blur'},
        {min: 3, max: 4, message: '长度在3-4个字符', trigger: 'blur'}
      ]
    }
  }
}

表单验证特点:

  1. 采用Element UI的表单验证机制

  2. 对用户名、密码、验证码都设置了必填和长度验证

  3. 触发方式为blur(失去焦点时验证)

1.3 验证码组件

系统集成了一个独立的验证码组件ValidCode

复制代码
<ValidCode @input="createValidCode" style="margin-left: 15px;margin-top: 5px;"/>
复制代码
methods: {
  createValidCode(data) {
    this.validCode = data
  }
}

验证码功能特点:

  • 点击可刷新验证码

  • 不区分大小写验证

  • 通过自定义事件传递验证码值

1.4 登录逻辑处理

复制代码
loginClick() {
  this.$refs["userForm"].validate(valid => {
    if (valid) { // 表单校验合法
      // 验证码校验
      if (this.user.validCode.toLowerCase() !== this.validCode.toLowerCase()) {
        this.$message.error("验证码错误")
        return false
      }
      // 发送登录请求
      this.$http.post("/big/login", this.user).then(res => {
        if (res.data.code === "200") {
          // 存储用户信息和菜单
          localStorage.setItem("user", JSON.stringify(res.data.object))
          localStorage.setItem("menuList", JSON.stringify(res.data.object.menuList))
          setRoutes() // 动态设置路由
          // 根据角色跳转不同页面
          if (res.data.object.role === "white") {
            this.$router.push("/main") // 前台首页
          } else {
            this.$router.push("/index_home") // 后台首页
          }
        } else {
          this.$message.error(res.data.message)
        }
      })
    }
  })
}

登录流程:

  1. 表单验证通过后检查验证码

  2. 发送登录请求到后端

  3. 成功后存储用户信息和菜单权限

  4. 动态设置路由

  5. 根据用户角色跳转到不同首页

二、后端登录接口实现

2.1 登录接口核心代码

复制代码
@PostMapping("/login")
public Res login(@RequestBody User user) {
    // 密码SHA256加密
    user.setPassword(MyUtils.getSHA256StrJava(user.getPassword()));
    
    // 查询用户
    QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
    userQueryWrapper.eq("name", user.getName());
    userQueryWrapper.eq("password", user.getPassword());
    User existUser = userMapper.selectOne(userQueryWrapper);
    
    if (existUser == null) {
        return Res.error(Constants.CODE_600, "用户名或密码错误");
    }
    
    // 生成Token
    String token = Token.productToken(existUser);
    existUser.setToken(token);
    
    // 处理角色权限
    Role role = new Role();
    role.setName(existUser.getRole());
    Role existRole = roleMapper.selectOne(roleQueryWrapper);
    
    // 构建菜单权限树
    List<Integer> menuIdList = new ArrayList<>();
    if (existRole.getMenuIds() != null) {
        // 处理菜单ID字符串
        String menuIds = existRole.getMenuIds().replace("[", "").replace("]", "");
        String[] tempArray = menuIds.split(",");
        for (String temp : tempArray) {
            menuIdList.add(Integer.parseInt(temp));
        }
    }
    
    // 补充父菜单ID
    List<Integer> tempList = new ArrayList<>(menuIdList);
    for (Integer menuId : menuIdList) {
        Menu menu = menuMapper.selectById(menuId);
        if (menu != null && menu.getFather() != null && !tempList.contains(menu.getFather())) {
            tempList.add(menu.getFather());
        }
    }
    
    // 构建菜单树结构
    List<Menu> menuList = menuMapper.selectBatchIds(tempList);
    List<Menu> fatherMenuList = menuList.stream()
        .filter(temp -> temp.getFather() == null)
        .collect(Collectors.toList());
    
    for (Menu item : fatherMenuList) {
        List<Menu> childrenList = menuList.stream()
            .filter(temp -> item.getId().equals(temp.getFather()))
            .collect(Collectors.toList());
        item.setChildren(childrenList);
    }
    
    existUser.setMenuList(fatherMenuList);
    return Res.success(existUser);
}

2.2 后端登录处理流程

  1. 密码加密处理

    • 使用SHA256算法对用户密码加密

    • 加密后与数据库存储的密码比对

  2. 用户查询

    • 使用MyBatis-Plus的QueryWrapper构建查询条件

    • 同时匹配用户名和密码

  3. Token生成

    • 登录成功后生成Token

    • Token将用于后续请求的身份验证

  4. 权限处理

    • 查询用户角色对应的菜单权限

    • 处理菜单ID字符串转换为列表

    • 补充必要的父菜单ID

    • 构建树形菜单结构

  5. 返回结果

    • 返回包含Token和菜单权限的用户信息

    • 前端将使用这些信息初始化路由和界面

三、关键技术点解析

3.1 动态路由实现

前端在登录成功后调用setRoutes()方法动态设置路由:

复制代码
setRoutes() // 动态设置路由

原理是根据后端返回的菜单权限,动态添加路由配置,实现权限控制。

3.2 密码安全策略

  1. 前端不存储密码明文

  2. 传输过程建议使用HTTPS

  3. 后端使用SHA256加密存储

  4. 数据库不存储明文密码

3.3 菜单权限树构建

后端通过以下步骤构建菜单树:

  1. 从角色配置中获取菜单ID列表

  2. 补充必要的父菜单ID

  3. 查询完整的菜单信息

  4. 构建父子关系的树形结构

复制代码
List<Menu> fatherMenuList = menuList.stream()
    .filter(temp -> temp.getFather() == null)
    .collect(Collectors.toList());

for (Menu item : fatherMenuList) {
    List<Menu> childrenList = menuList.stream()
        .filter(temp -> item.getId().equals(temp.getFather()))
        .collect(Collectors.toList());
    item.setChildren(childrenList);
}

四、系统扩展与优化建议

  1. 登录安全增强

    • 添加登录失败次数限制

    • 实现IP异常检测

    • 考虑添加二次验证

  2. 性能优化

    • 菜单权限缓存

    • Token刷新机制

    • 接口响应优化

  3. 功能扩展

    • 第三方登录集成

    • 多因素认证

    • 登录日志记录

五、总结

本文详细介绍了基于Vue和SpringBoot的前后端分离登录系统的设计与实现,涵盖了从前端表单验证到后端权限处理的完整流程。该系统具有以下特点:

  1. 前后端完全分离,通过API交互

  2. 完善的表单验证机制

  3. 动态路由和权限控制

  4. 安全的密码处理策略

  5. 灵活的菜单权限配置

通过这种架构,系统具有良好的扩展性和维护性,可以方便地适应各种业务需求的变化。

相关推荐
Coder_Boy_1 天前
基于SpringAI的在线考试系统-企业级软件研发工程应用规范案例
java·运维·spring boot·软件工程·devops
佛系打工仔1 天前
K线绘制前言
前端
indexsunny1 天前
互联网大厂Java面试实战:微服务、Spring Boot与Kafka在电商场景中的应用
java·spring boot·微服务·面试·kafka·电商
SUDO-11 天前
Spring Boot + Vue 2 的企业级 SaaS 多租户招聘管理系统
java·spring boot·求职招聘·sass
sheji34161 天前
【开题答辩全过程】以 基于spring boot的停车管理系统为例,包含答辩的问题和答案
java·spring boot·后端
遇见~未来1 天前
JavaScript数组全解析:从本质到高级技巧
开发语言·前端·javascript
石像鬼₧魂石1 天前
80 端口(Web 服务)渗透测试完整总结(含踩坑 + 绕过 + 实战流程)
linux·运维·服务器·前端·网络·阿里云
中年程序员一枚1 天前
多数据源的springboot进行动态连接方案
java·spring boot·后端
w***76551 天前
SpringBoot集成MQTT客户端
java·spring boot·后端
C_心欲无痕1 天前
nginx - 核心概念
运维·前端·nginx