以下是一个使用Spring Security实现用户登录和注册功能的步骤和代码示例。我们将构建一个简单的 RESTful API,用户可以通过它进行注册和登录。
技术栈
Spring Boot 3.4.1
Spring Security
JPA(Hibernate)
MySQL数据库
项目结构
src/main/java/com/example/demo
├── controller# REST API 控制器
├── model# 实体类
├── repository# 数据库交互接口
├── config# 配置
├── service# 业务逻辑
└── DemoApplication.java
步骤 1:添加依赖
在build.gradle 中添加必要依赖:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.mysql:mysql-connector-j'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
步骤 2:创建实体类
User 实体类
创建 User 类来表示用户信息:
package com.example.demo.model;
import jakarta.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String password;
getter and setter...
}
步骤 3:创建 JPA 仓库
UserRepository
package com.example.demo.repository;
import com.example.demo.model.User;
import org.springframework.data.repository.CrudRepository;
import java.util.Optional;
//@Repository
public interface UserRepository extends CrudRepository<User, Long> {
Optional<User> findByUsername(String username);
}
步骤 4:创建服务层
UserService
package com.example.demo.service;
import com.example.demo.model.User;
import com.example.demo.repository.UserRepository;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
public User registerUser(String username, String password) {
if (userRepository.findByUsername(username).isPresent()) {
throw new RuntimeException("Username is already taken.");
}
User user = new User();
user.setUsername(username);
user.setPassword(passwordEncoder.encode(password));
return userRepository.save(user);
}
public Boolean loginUser(String username, String password) {
Optional<User> user = userRepository.findByUsername(username);
return user.filter(value -> passwordEncoder.matches(password, value.getPassword())).isPresent();
}
}
步骤 5:配置 Spring Security
SecurityConfig
package com.example.demo.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/register", "/api/login").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
}
步骤 6:创建控制器
AuthController
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class AuthController {
private final UserService userService;
public AuthController(UserService userService) {
this.userService = userService;
}
@PostMapping("/register")
public ResponseEntity<?> register(@RequestBody User user) {
try {
User registeredUser = userService.registerUser(user.getUsername(), user.getPassword());
return ResponseEntity.ok(registeredUser);
} catch (RuntimeException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody User user) {
if (userService.loginUser(user.getUsername(), user.getPassword())) {
return ResponseEntity.ok("Login successful!");
}
return ResponseEntity.badRequest().body("Login fail");
}
}
步骤 7:配置 MySQL 数据库
application.properties
spring.application.name=demo
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/myreadinglist
spring.datasource.username=root
spring.datasource.password=pass
spring.jpa.hibernate.ddl-auto=update
测试 API
1. 注册用户
- 请求:
POST /api/register - 请求体:
{
"username": "testuser",
"password": "password123"
}
2. 登录用户
- 请求:
POST /api/login
{
"username": "testuser",
"password": "password123"
}