Spring Boot 安全登录系统:前后端分离实现

关键词:Spring Boot、安全登录、JWT、Shiro / Spring Security、前后端分离、Vue、MySQL


详细代码请参考这篇文章:完整 Spring Boot + Vue 登录

✅ 摘要

在现代 Web 应用中,用户登录与权限控制是系统安全性的基础环节。本文将手把手带你实现一个基于 Spring Boot + JWT + Shiro/Spring Security 的安全登录系统,并配合前端 Vue 实现前后端分离架构。

内容涵盖:

  • 后端接口设计(登录、注册、权限验证)
  • 使用 JWT 生成 Token
  • 使用 Shiro 或 Spring Security 实现权限管理
  • 前端 Vue 登录页面与 Token 存储示例
  • 跨域配置、拦截器校验 Token
  • 完整数据库表结构(MySQL)

每部分都配有 完整的 Java 示例代码、Vue 页面代码和数据库脚本


📌 一、项目结构说明

springboot-login/
├── backend/            # Spring Boot 后端模块
│   ├── src/main/java     # Java源码
│   └── application.yml   # 配置文件
├── frontend/           # Vue 前端模块(可选)
│   ├── src/views         # 登录页组件
│   └── main.js           # Axios 请求封装
└── README.md

📌 二、数据库设计(MySQL)

用户表:sys_user

CREATE TABLE sys_user (id BIGINT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL UNIQUE,password VARCHAR(100) NOT NULL,nickname VARCHAR(50),create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);

📌 三、后端实现(Spring Boot + JWT)

1. 添加依赖(pom.xml)

<!-- Spring Boot Starter -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!-- JWT 工具 -->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency><!-- MyBatis Plus -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version>
</dependency><!-- Shiro 权限框架(可替换为 Spring Security) -->
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId><version>1.9.1</version>
</dependency>

2. JWT 工具类(JwtUtils.java)

import io.jsonwebtoken.*;
import java.util.Date;public class JwtUtils {private static final String SECRET = "your-secret-key";private static final long EXPIRATION = 86400000; // 24小时public static String generateToken(String username) {return Jwts.builder().setSubject(username).setExpiration(new Date(System.currentTimeMillis() + EXPIRATION)).signWith(SignatureAlgorithm.HS512, SECRET).compact();}public static String parseToken(String token) {return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody().getSubject();}
}

3. 登录接口(UserController.java)

@RestController
@RequestMapping("/api/auth")
public class AuthController {@Autowiredprivate UserService userService;@PostMapping("/login")public ResponseEntity<?> login(@RequestBody LoginRequest request) {SysUser user = userService.findByUsername(request.getUsername());if (user == null || !user.getPassword().equals(request.getPassword())) {throw new RuntimeException("用户名或密码错误");}String token = JwtUtils.generateToken(user.getUsername());return ResponseEntity.ok().header("Authorization", "Bearer " + token).build();}
}

4. 自定义拦截器(JwtInterceptor.java)

@Component
public class JwtInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");if (token != null && token.startsWith("Bearer ")) {token = token.substring(7);String username = JwtUtils.parseToken(token);// 可以结合 Shiro 或 Spring Security 设置认证信息UsernamePasswordToken shiroToken = new UsernamePasswordToken(username, "");SecurityUtils.getSubject().login(shiroToken);}return true;}
}

5. 注册拦截器(WebConfig.java)

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate JwtInterceptor jwtInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(jwtInterceptor).addPathPatterns("/**").excludePathPatterns("/api/auth/login");}
}

📌 四、前端实现(Vue + Axios)

1. 登录页面组件(Login.vue)

<template><div><input v-model="username" placeholder="用户名"><input v-model="password" type="password" placeholder="密码"><button @click="login">登录</button></div>
</template><script>
export default {data() {return {username: '',password: ''};},methods: {async login() {const res = await this.$axios.post('/api/auth/login', {username: this.username,password: this.password});const token = res.headers.authorization;localStorage.setItem('token', token);this.$router.push('/');}}
};
</script>

2. Axios 封装(main.js)

import axios from 'axios';const apiClient = axios.create({baseURL: 'http://localhost:8080',
});// 请求拦截器添加 Token
apiClient.interceptors.request.use(config => {const token = localStorage.getItem('token');if (token) {config.headers.Authorization = token;}return config;
});Vue.prototype.$axios = apiClient;

📌 五、跨域配置(application.yml)

spring:mvc:async:request-timeout: -1cors:allowed-origins: "*"allowed-methods: "*"allowed-headers: "*"

✅ 总结

功能技术栈说明
登录接口Spring Boot接收用户名密码,返回 Token
Token 管理JWT生成与解析 Token
权限控制Shiro / Spring Security控制访问权限
前端登录Vue使用 Axios 发起请求并存储 Token
Token 校验拦截器每次请求校验 Token 并设置用户上下文

📚 参考资料

  • Spring Boot 官方文档
  • JWT 官方网站
  • Apache Shiro 文档

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

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

相关文章

Docker高级管理--Dockerfile 镜像制作

目录 一&#xff1a;Docker 镜像管理 1:Docker 镜像结构 &#xff08;1&#xff09; 镜像分层核心概念 &#xff08;2&#xff09;镜像层特性 &#xff08;3&#xff09;关键操作命令 &#xff08;4&#xff09;优化建议 2&#xff1a;Dockerfile介绍 &#xff08;1&…

Leetcode力扣解题记录--第42题 接雨水(动规和分治法)

题目链接&#xff1a;42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 这里我们可以用两种方法去解决巧妙地解决这个题。首先来看一下题目 题目描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。…

宝塔配置pgsql可以远程访问

本地navicat premium 17.0 可以远程访问pgsql v16.1宝塔的软件商店里&#xff0c;找到pgsql管理器&#xff1b;在pgsql管理器里找到客户端认证&#xff1a;第二步&#xff1a;配置修改&#xff0c;CtrlF 查找listen_addresses关键字&#xff1b;第三步&#xff1a;在navicat里配…

小架构step系列12:单元测试

1 概述 测试的种类很多&#xff1a;单元测试、集成测试、系统测试等&#xff0c;程序员写代码进行测试的可以称为白盒测试&#xff0c;单元测试和集成测试都可以进行白盒测试&#xff0c;可以理解为单元测试是对某个类的某个方法进行测试&#xff0c;集成测试则是测试一连串的…

SpringBoot3-Flowable7初体验

目录简介准备JDKMySQLflowable-ui创建流程图要注意的地方编码依赖和配置控制器实体Flowable任务处理类验证启动程序调用接口本文源码参考简介 Flowable是一个轻量的Java业务流程引擎&#xff0c;用于实现业务流程的管理和自动化。相较于老牌的Activiti做了一些改进和扩展&…

phpMyAdmin:一款经典的MySQL在线管理工具又回来了

phpMyAdmin 是一个免费开源、基于 Web 的 MySQL/MariaDB 数据库管理和开发工具。它提供了一个直观的图形用户界面&#xff0c;使得我们无需精通复杂的 SQL 命令也能执行大多数数据库管理任务。 phpMyAdmin 项目曾经暂停将近两年&#xff0c;不过 2025 年又开始发布新版本了。 …

存储服务一NFS文件存储概述

前言&#xff1a; 网络文件系统&#xff08;Network File System&#xff0c;NFS&#xff09;诞生于1984年&#xff0c;由Sun Microsystems首创&#xff0c;旨在解决异构系统间的文件共享需求。作为一种基于客户端-服务器架构的分布式文件协议&#xff0c;NFS允许远程主机通过T…

libimagequant 在 mac 平台编译双架构

在 macOS 上编译 libimagequant 的双架构&#xff08;aarch64 x86_64&#xff09;通用二进制库&#xff0c;以下是完整步骤&#xff1a;​​1. 准备 Rust 工具链​​ # 安装两个目标平台 rustup target add aarch64-apple-darwin x86_64-apple-darwin# 确认安装成功 rustup ta…

暑期自学嵌入式——Day01(C语言阶段)

点关注不迷路哟。你的点赞、收藏&#xff0c;一键三连&#xff0c;是我持续更新的动力哟&#xff01;&#xff01;&#xff01; 主页&#xff1a; 一位搞嵌入式的 genius-CSDN博客https://blog.csdn.net/m0_73589512?spm1011.2682.3001.5343感悟&#xff1a; 今天我认为最重…

Flutter基础(前端教程⑧-数据模型)

这个示例展示了如何创建数据模型、解析 JSON 数据&#xff0c;以及在 UI 中使用这些数据&#xff1a;import package:flutter/material.dart; import dart:convert;void main() {// 示例&#xff1a;手动创建User对象final user User(id: 1,name: 张三,age: 25,email: zhangsa…

SSRF10 各种限制绕过之30x跳转绕过协议限制

ssrf漏洞在厂商的处理下可能进行一些特殊处理导致我们无法直接利用漏洞 有以下四种&#xff1a; 1.ip地址限制绕过 2.域名限制绕过 3.30x跳转绕过域名限制 4.DNS rebinding绕过内网ip限制 本章我们讲30x跳转绕过域名限制 30x跳转绕过域名限制 之前我们使用ssrf漏洞时可以…

DNS解析过程和nmap端口扫描

目录 DNS解析流程&#xff1a; nmap端口扫描 指定扫描方式 TCP全连接扫描 -sT SYN半连接扫描 -sS -sT和 -sS的区别 Linux提权 利用好谷歌语法查找敏感信息 如果自己搭建了网站文件要放在phpstudy_pro\WWW下。 如果想要使用域名访问网站&#xff0c;需要在phpstudy_pro…

【基于开源大模型(如deepseek)开发应用及其发展趋势的一点思考】

1. 开源大模型技术发展现状1.1 DeepSeek等主流开源大模型的技术特性分析 DeepSeek作为当前最具代表性的开源大模型之一&#xff0c;其技术架构具有多项创新特性。该模型采用混合专家架构(MoE)&#xff0c;通过将视觉编码分离为"理解"和"生成"两条路径&…

java8 ConcurrentHashMap 桶级别锁实现机制

Java 8 ConcurrentHashMap 桶级别锁实现机制 Java 8 中的 ConcurrentHashMap 抛弃了分段锁设计&#xff0c;采用了更细粒度的桶级别锁&#xff08;bucket-level locking&#xff09;实现&#xff0c;这是其并发性能提升的关键。下面详细解析其实现原理&#xff1a; 1. 基本实现…

Python正则表达式实战指南

一 正则表达式库正则表达式是文本处理中不可或缺的强大工具&#xff0c;Python通过re模块提供了完整的正则表达式支持。本文将详细介绍re模块中最常用的match()、search()和findall()函数&#xff0c;以及贪婪模式与非贪婪模式的区别&#xff0c;帮助读者掌握Python中正则表达式…

使用球体模型模拟相机成像:地面与天空的可见性判断与纹理映射

在传统相机模拟中&#xff0c;地面通常被建模为一个平面&#xff08;Plane&#xff09;&#xff0c;这在低空场景下是合理的。但在更大视场范围或远距观察时&#xff0c;地球的曲率不可忽视。因此&#xff0c;我们需要将地面模型从平面升级为球体&#xff0c;并基于球面与光线的…

Agent自动化与代码智能

核心问题&#xff1a; 现在很多团队做AI系统有个大毛病&#xff1a;只顾追求“高大上”的新技术&#xff08;尤其是AI Agent&#xff09;&#xff0c;不管实际业务需不需要。 结果系统搞得又贵、又复杂、还容易出错。大家被“Agent”这个概念搞晕了&#xff1a;到底啥时候用简单…

SQL141 试卷完成数同比2020年的增长率及排名变化

SQL141 试卷完成数同比2020年的增长率及排名变化 withtemp as (selectexam_id,tag,date(submit_time) as submit_timefromexamination_infoleft join exam_record using (exam_id)wheresubmit_time is not null),2021_temp as (selecttag,count(*) as exam_cnt_21,rank() over…

C语言<数据结构-单链表>

链表是一种常见且重要的数据结构&#xff0c;在 C 语言中&#xff0c;它通过指针将一系列的节点连接起来&#xff0c;每个节点可以存储不同类型的数据。相比数组&#xff0c;链表在插入和删除元素时不需要移动大量数据&#xff0c;具有更好的灵活性&#xff0c;尤其适合处理动态…

archive/tar: unknown file mode ?rwxr-xr-x

这个是我在docker build报错的&#xff0c;这是一个node.js项目。我猜你也是一个node.js下的项目&#xff0c;或者前端项目。 解决方法&#xff1a; .dockerignore里面写一下node_modules就行了。 未能解决&#xff1a;archive/tar&#xff1a;未知文件模式&#xff1f;rwxr-…