關鍵詞: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 文檔