> ## Documentation Index
> Fetch the complete documentation index at: https://blog.pig4cloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 无密码时代来临！Spring Security 6.4魔法链接登录全解析

> 深入解析 Spring Security 6.4 一次性令牌登录功能，从原理到实践的最佳指南

# Spring Security 6.4 一次性令牌登录详解

> 作者：lengleng\
> 发布日期：2025-01-31

## 1. 概述

Spring Security 6.4 引入了一项新的安全特性 —— 一次性令牌登录（One-Time Token Login）。这种登录方式允许用户通过邮件接收一个魔法链接（Magic Link）来完成身份验证，无需传统的用户名和密码组合。这种方式不仅提升了用户体验，还增强了系统的安全性。

比如笔者上篇文章提到的 mintlify 文档工具，默认提供的就是这种方式。

<img src="https://minio.pigx.vip/oss/202501/1738056898.png" alt="mintlify 邮件登录" />

### 1.1 登录流程图

```mermaid theme={null}
sequenceDiagram
    participant User
    participant System
    participant EmailService

    User->>System: 提交邮箱
    System->>EmailService: 生成并发送魔法链接
    EmailService->>User: 发送含链接邮件
    User->>System: 点击魔法链接
    alt 验证成功
        System->>User: 登录成功
    else 验证失败
        System->>User: 显示错误提示
    end
```

### 1.2 技术架构图

```mermaid theme={null}
graph TB
    A[用户界面] --> B[Spring Security过滤器链]
    B --> C[OneTimeTokenAuthenticationFilter]
    C --> D[OneTimeTokenRepository]
    C --> E[UserDetailsService]
    D --> F[(令牌存储)]
    E --> G[(用户数据库)]

    style A fill:#f9f,stroke:#333,stroke-width:2px
    style B fill:#bbf,stroke:#333,stroke-width:2px
    style C fill:#dfd,stroke:#333,stroke-width:2px
    style D fill:#dfd,stroke:#333,stroke-width:2px
    style E fill:#dfd,stroke:#333,stroke-width:2px
    style F fill:#fdd,stroke:#333,stroke-width:2px
    style G fill:#fdd,stroke:#333,stroke-width:2px
```

## 2. 核心概念

### 2.1 一次性令牌

* 一次性令牌是一个临时的、只能使用一次的认证凭证
* 通常以 URL 参数或者令牌字符串的形式发送给用户
* 有效期通常为 5-15 分钟

### 2.2 魔法链接

* 包含一次性令牌的 URL 链接
* 通过邮件发送给用户
* 点击即可完成身份验证

## 3. 实现原理

### 3.1 认证流程

1. 令牌生成：采用密码学安全随机数生成器生成 128 位随机令牌
2. 令牌存储：支持多种存储方式（内存、Redis、数据库）
3. 邮件发送：异步发送包含令牌的魔法链接
4. 令牌验证：过滤器链中校验令牌有效性
5. 会话建立：成功验证后创建安全上下文

### 3.2 核心组件

| 组件名称                     | 职责描述     |
| ------------------------ | -------- |
| OneTimeTokenFilter       | 拦截令牌验证请求 |
| OneTimeTokenManager      | 管理令牌生命周期 |
| TokenExpirationStrategy  | 定义令牌过期策略 |
| TokenVerificationHandler | 处理令牌验证逻辑 |

## 4. 实现步骤

### 4.1 添加依赖

```xml theme={null}
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
```

### 4.2 配置一次性令牌服务

```java theme={null}
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/login/**").permitAll()
                .anyRequest().authenticated()
            )
            .oneTimeTokenLogin(oneTime -> oneTime
                .tokenRepository(tokenRepository())
                .tokenValidityDuration(Duration.ofMinutes(5))
            );
        return http.build();
    }

    @Bean
    public OneTimeTokenRepository tokenRepository() {
        return new InMemoryOneTimeTokenRepository();
    }
}
```

### 4.3 实现令牌生成和发送

```java theme={null}
@Service
public class OneTimeTokenService {

    @Autowired
    private OneTimeTokenRepository tokenRepository;

    @Autowired
    private EmailService emailService;

    public void sendLoginToken(String email) {
        String token = generateToken();
        tokenRepository.save(new OneTimeToken(token, email));

        String loginLink = "https://your-domain.com/login/verify?token=" + token;
        emailService.sendLoginLink(email, loginLink);
    }

    private String generateToken() {
        return UUID.randomUUID().toString();
    }
}
```

## 5. 总结

Spring Security 6.4 的一次性令牌登录功能为应用提供了一种现代、安全的身份验证方式。通过合理的配置和实现，可以在保证安全性的同时提供良好的用户体验。在实际应用中，需要根据具体场景调整配置参数，并结合其他安全措施，构建完整的安全解决方案。
