Skip to content

企业级实战案例

项目结构

text
com.example.demo
  ├── auth
  │   ├── AuthController.java
  │   ├── LoginRequest.java
  │   ├── LoginResponse.java
  │   └── RegisterRequest.java
  ├── security
  │   ├── SecurityConfig.java
  │   ├── JwtAuthenticationFilter.java
  │   ├── JwtService.java
  │   ├── RestAuthenticationEntryPoint.java
  │   └── RestAccessDeniedHandler.java
  ├── service
  │   └── CustomUserDetailsService.java
  ├── repository
  └── domain

注册接口

java
@RestController
@RequestMapping("/api/auth")
class AuthController {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    AuthController(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @PostMapping("/register")
    void register(@RequestBody RegisterRequest request) {
        userRepository.save(new UserEntity(request.username(), passwordEncoder.encode(request.password())));
    }
}
java
public record RegisterRequest(String username, String password) {}

登录接口

java
@PostMapping("/login")
LoginResponse login(@RequestBody LoginRequest request) {
    Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(request.username(), request.password()));
    String token = jwtService.generate(authentication.getName(), List.of("ROLE_USER"));
    return new LoginResponse(token);
}
java
public record LoginRequest(String username, String password) {}
public record LoginResponse(String accessToken) {}

当前登录用户接口

java
@GetMapping("/me")
Map<String, Object> me(Authentication authentication) {
    return Map.of(
            "name", authentication.getName(),
            "authorities", authentication.getAuthorities().stream()
                    .map(GrantedAuthority::getAuthority)
                    .toList());
}

管理员接口

java
@PreAuthorize("hasRole('ADMIN')")
@DeleteMapping("/users/{id}")
void deleteUser(@PathVariable Long id) {
}

企业项目里的常见拆分

  • 登录注册接口独立在 auth 模块。
  • Token 解析和安全异常处理独立在 security 模块。
  • 用户查询逻辑落在 servicerepository
  • 管理端、开放 API、内部接口建议用多条 SecurityFilterChain 分开。

常见问题

  • 注册时密码未编码,导致登录校验永远失败。
  • JWT 过滤器插在 AuthorizationFilter 后面,导致请求始终未认证。
  • permitAll 范围写错,把敏感接口暴露出去。
  • Session 与 JWT 混用但未明确策略,出现状态不一致。