关键词: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 {
@Autowired
private 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 {
@Override
public 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 {
@Autowired
private JwtInterceptor jwtInterceptor;
@Override
public 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: -1
cors:
allowed-origins: "*"
allowed-methods: "*"
allowed-headers: "*"
✅ 总结
功能 | 技术栈 | 说明 |
---|---|---|
登录接口 | Spring Boot | 接收用户名密码,返回 Token |
Token 管理 | JWT | 生成与解析 Token |
权限控制 | Shiro / Spring Security | 控制访问权限 |
前端登录 | Vue | 使用 Axios 发起请求并存储 Token |
Token 校验 | 拦截器 | 每次请求校验 Token 并设置用户上下文 |