测试环境下如何生成Firebase Auth伪造JWT令牌及模拟登录?
测试环境下Spring Boot Firebase认证的伪造JWT与模拟登录方案
针对你的场景,这里提供两种可落地的实现方案,覆盖伪造JWT生成和登录流程测试的需求:
方案一:禁用签名验证+自定义伪造JWT生成
这个方案基于你提到的思路完善,通过测试环境专属配置跳过Firebase JWT的签名验证,同时提供工具方法一键生成带自定义用户属性的JWT。
步骤1:编写测试环境安全配置
创建仅在test profile下生效的配置类,替换默认的JwtDecoder,跳过签名验证:
@Configuration @Profile("test") public class TestAuthConfig { @Bean public JwtDecoder jwtDecoder() { // 初始化Nimbus解码器,JWKS地址保留真实地址,后续跳过签名验证 NimbusJwtDecoder decoder = NimbusJwtDecoder.withJwkSetUri("https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com") .build(); // 自定义验证逻辑,跳过签名校验,可按需保留声明检查 decoder.setJwtValidator(jwt -> Mono.just(jwt)); return decoder; } // 一键生成伪造用户JWT的工具方法 public String generateFakeUserJwt() { String randomUserId = UUID.randomUUID().toString(); String randomEmail = "fake-" + UUID.randomUUID() + "@test.com"; // 生成符合Firebase格式的JWT,签名密钥任意(测试环境跳过验证) return Jwts.builder() .setSubject(randomUserId) // 对应Firebase用户ID的sub字段 .claim("email", randomEmail) .claim("email_verified", true) // 模拟已验证邮箱 .claim("totp_enabled", true) // 模拟已启用TOTP .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1小时有效期 .signWith(SignatureAlgorithm.HS256, "test-only-secret") .compact(); } }
步骤2:在测试中使用伪造JWT
在接口测试类中注入工具方法,生成JWT后携带在请求头中访问受保护接口:
@SpringBootTest @ActiveProfiles("test") public class ProtectedEndpointTest { @Autowired private TestAuthConfig testAuthConfig; @Autowired private MockMvc mockMvc; @Test public void testAccessWithFakeUser() throws Exception { String fakeJwt = testAuthConfig.generateFakeUserJwt(); mockMvc.perform(get("/api/user/profile") .header("Authorization", "Bearer " + fakeJwt)) .andExpect(status().isOk()) .andExpect(jsonPath("$.email").matches("fake-.*@test.com")); } }
方案二:模拟Firebase登录流程
如果需要测试完整的登录链路(比如后端调用Firebase接口验证账号密码的流程),可以用WireMock模拟Firebase的认证接口,返回伪造的用户凭证。
步骤1:配置WireMock模拟Firebase接口
在测试类中启用WireMock,模拟Firebase的登录接口返回伪造JWT:
@AutoConfigureWireMock(port = 8089) @SpringBootTest(properties = {"firebase.auth.base-url=http://localhost:8089"}) @ActiveProfiles("test") public class LoginFlowTest { @Autowired private TestAuthConfig testAuthConfig; @Autowired private MockMvc mockMvc; @Test public void testFullLoginFlow() throws Exception { // 模拟Firebase密码登录接口,返回伪造JWT stubFor(post(urlEqualTo("/v1/accounts:signInWithPassword")) .withRequestBody(containing("email")) .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withBody(""" { "idToken": "%s", "email": "fake-login@test.com", "emailVerified": true, "localId": "fake-login-id" } """.formatted(testAuthConfig.generateFakeUserJwt())))); // 模拟前端发起登录请求,后端调用Firebase验证后返回令牌 mockMvc.perform(post("/api/auth/login") .contentType(MediaType.APPLICATION_JSON) .content(""" { "email": "fake-login@test.com", "password": "fake-pass" } """)) .andExpect(status().isOk()) .andExpect(jsonPath("$.token").exists()); } }
关键注意事项
- 所有测试配置必须通过
@Profile("test")隔离,绝对不能渗透到生产环境。 - 生成JWT时尽量对齐Firebase的标准声明字段,保证测试场景与生产一致。
- 使用WireMock时,需修改后端Firebase客户端的配置地址为WireMock的本地地址。
内容的提问来源于stack exchange,提问作者user2741831
相关产品推荐
相关产品推荐

