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'}]}} }
表单验证特点:
采用Element UI的表单验证机制
对用户名、密码、验证码都设置了必填和长度验证
触发方式为
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)}})}}) }
登录流程:
表单验证通过后检查验证码
发送登录请求到后端
成功后存储用户信息和菜单权限
动态设置路由
根据用户角色跳转到不同首页
二、后端登录接口实现
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, "用户名或密码错误");}// 生成TokenString 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));}}// 补充父菜单IDList<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 后端登录处理流程
密码加密处理:
使用SHA256算法对用户密码加密
加密后与数据库存储的密码比对
用户查询:
使用MyBatis-Plus的QueryWrapper构建查询条件
同时匹配用户名和密码
Token生成:
登录成功后生成Token
Token将用于后续请求的身份验证
权限处理:
查询用户角色对应的菜单权限
处理菜单ID字符串转换为列表
补充必要的父菜单ID
构建树形菜单结构
返回结果:
返回包含Token和菜单权限的用户信息
前端将使用这些信息初始化路由和界面
三、关键技术点解析
3.1 动态路由实现
前端在登录成功后调用setRoutes()
方法动态设置路由:
setRoutes() // 动态设置路由
原理是根据后端返回的菜单权限,动态添加路由配置,实现权限控制。
3.2 密码安全策略
前端不存储密码明文
传输过程建议使用HTTPS
后端使用SHA256加密存储
数据库不存储明文密码
3.3 菜单权限树构建
后端通过以下步骤构建菜单树:
从角色配置中获取菜单ID列表
补充必要的父菜单ID
查询完整的菜单信息
构建父子关系的树形结构
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); }
四、系统扩展与优化建议
登录安全增强:
添加登录失败次数限制
实现IP异常检测
考虑添加二次验证
性能优化:
菜单权限缓存
Token刷新机制
接口响应优化
功能扩展:
第三方登录集成
多因素认证
登录日志记录
五、总结
本文详细介绍了基于Vue和SpringBoot的前后端分离登录系统的设计与实现,涵盖了从前端表单验证到后端权限处理的完整流程。该系统具有以下特点:
前后端完全分离,通过API交互
完善的表单验证机制
动态路由和权限控制
安全的密码处理策略
灵活的菜单权限配置
通过这种架构,系统具有良好的扩展性和维护性,可以方便地适应各种业务需求的变化。