You need to enable JavaScript to run this app. 在Spring Webflux中如何在端点执行前创建并持久化自定义用户对象
优惠活动
大模型
产品
解决方案
定价
更多

在Spring Webflux中如何在端点执行前创建并持久化自定义用户对象

实现方案

你可以通过自定义一个Spring WebFilter,在认证逻辑执行完成后自动完成用户存在性校验和创建操作,不需要修改现有接口代码。

1. 实现自定义自动创建用户过滤器

import org.springframework.core.Ordered
import org.springframework.core.annotation.Order
import org.springframework.security.core.context.ReactiveSecurityContextHolder
import org.springframework.stereotype.Component
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.server.WebFilter
import org.springframework.web.server.WebFilterChain
import reactor.core.publisher.Mono
import java.time.LocalDateTime

// 配置优先级保证在Spring Security认证过滤器之后执行
@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 10)
class UserAutoCreateFilter(
    // 替换为你自己项目的反应式用户Repository
    private val userRepository: UserRepository
) : WebFilter {
    override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
        // 只处理/secure路径下的已认证请求,避免不必要的数据库查询
        val requestPath = exchange.request.uri.path
        if (!requestPath.startsWith("/secure/")) {
            return chain.filter(exchange)
        }

        return ReactiveSecurityContextHolder.getContext()
            .map { it.authentication }
            // 过滤未认证、匿名的请求
            .filter { it.isAuthenticated && it.name != null && !"anonymousUser".equals(it.name) }
            .flatMap { auth ->
                val userOAuthUuid = auth.name
                // 校验用户是否已存在
                userRepository.existsByUuid(userOAuthUuid)
                    .filter { exists -> !exists }
                    .flatMap { 
                        // 首次访问则创建新用户
                        // 若需要更多用户属性,可以将auth强转为JwtAuthenticationToken,从JWT的Claims中获取
                        // val jwt = auth as JwtAuthenticationToken
                        // val email = jwt.token.getClaimAsString("email")
                        val newUser = User(
                            uuid = userOAuthUuid,
                            createTime = LocalDateTime.now()
                            // 补充其他需要的用户字段
                        )
                        userRepository.save(newUser)
                    }
            }
            // 无论用户是否是首次访问,都继续执行后续接口逻辑
            .then(chain.filter(exchange))
    }
}

2. 注意事项

  • 这里用到的UserRepository必须是反应式实现(比如继承R2dbcRepository),不能使用阻塞的JDBC/JPA实现,否则会在Webflux环境下抛出线程阻塞异常。
  • 过滤器加了@Component注解后会自动全局生效,无需额外注册,如果你希望手动注册到Spring Security过滤链中,也可以在springSecurityFilterChain方法中通过http.addFilterAfter()方法添加。

内容的提问来源于stack exchange,提问作者d35t1201

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 05:36:06