You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Spring Boot控制器中获取Firebase认证Token的UID

Spring Boot中从Firebase JWT Token获取UID的最优方案

核心思路

利用Spring Security OAuth2 Resource Server的JWT认证机制,将Token中的UID自动绑定到请求上下文,通过注解直接在Controller中获取,无需手动解析请求头或传递不安全的查询参数。


步骤1:配置JWT认证转换器

修改SecurityConfig,自定义JwtAuthenticationConverter,将Firebase Token中的UID提取为认证主体(Principal),方便后续在接口中直接获取。Firebase ID Token的UID默认存储在sub字段中,若你的Token使用user_id字段,可自行替换。

@Configuration
@EnableWebSecurity
class SecurityConfig {

    @Bean
    fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
        http.cors().and().csrf().disable()
            .authorizeHttpRequests { auth ->
                auth.antMatchers("/appauth/**").authenticated()
            }
            .oauth2ResourceServer { oauth2 ->
                oauth2.jwt { jwt ->
                    jwt.jwtAuthenticationConverter(jwtAuthenticationConverter())
                }
            }
        return http.build()
    }

    private fun jwtAuthenticationConverter(): JwtAuthenticationConverter {
        val converter = JwtAuthenticationConverter()
        // 可选:配置权限提取规则(如果需要基于Token的权限控制)
        val authoritiesConverter = JwtGrantedAuthoritiesConverter()
        authoritiesConverter.setAuthorityPrefix("ROLE_")
        converter.setJwtGrantedAuthoritiesConverter(authoritiesConverter)

        // 提取UID作为认证主体
        converter.setPrincipalExtractor { jwt: Jwt ->
            // Firebase Token的UID对应sub字段,根据实际Token结构调整
            jwt.subject
        }
        return converter
    }
}

步骤2:在Controller中直接获取UID

使用@AuthenticationPrincipal注解,直接将认证后的UID注入到接口方法参数中,无需任何额外解析操作:

@GetMapping(path = ["/projects"])
fun getProjects(@AuthenticationPrincipal uid: String): String {
    val user = someRepository.getUserByUid(uid)
    return user.projects
}

进阶:自定义用户主体(可选)

如果需要从Token中提取更多用户信息(如邮箱、角色等),可以封装一个自定义的UserPrincipal类,让代码更具可读性:

1. 定义UserPrincipal类

data class UserPrincipal(
    val uid: String,
    // 可添加其他字段,如email、displayName等,从Jwt claims中提取
    val email: String? = null
) : Principal {
    override fun getName(): String = uid
}

2. 更新转换器的PrincipalExtractor

private fun jwtAuthenticationConverter(): JwtAuthenticationConverter {
    val converter = JwtAuthenticationConverter()
    // 权限配置保持不变
    val authoritiesConverter = JwtGrantedAuthoritiesConverter()
    authoritiesConverter.setAuthorityPrefix("ROLE_")
    converter.setJwtGrantedAuthoritiesConverter(authoritiesConverter)

    // 提取多个字段封装为UserPrincipal
    converter.setPrincipalExtractor { jwt: Jwt ->
        UserPrincipal(
            uid = jwt.subject,
            email = jwt.claims["email"]?.toString()
        )
    }
    return converter
}

3. Controller中使用自定义主体

@GetMapping(path = ["/projects"])
fun getProjects(@AuthenticationPrincipal userPrincipal: UserPrincipal): String {
    val user = someRepository.getUserByUid(userPrincipal.uid)
    return user.projects
}

优势说明

  • 安全可靠:避免了手动解析Token的出错风险,也杜绝了将UID作为查询参数传递的安全隐患。
  • 代码简洁:无需重复编写Token解析逻辑,直接通过注解获取关键信息,降低冗余代码。
  • 扩展性强:后续如需提取Token中其他字段,只需修改转换器和自定义主体即可,无需改动Controller逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:01:05