Go服务从Auth0迁移Firebase后,如何测试认证登录?
Go服务Firebase认证登录测试的正确姿势
你之前踩的几个误区
- Go Firebase Admin SDK是后端管理工具,压根不提供用户端的登录功能,它的作用是验证Token、管理用户,不是模拟用户登录拿Token的。
- Firebase Auth模拟器是支持REST API的,只是你没找对路子——官方的Auth REST接口几乎都能在模拟器上用,只要替换base URL就行。
- 模拟客户端请求时,模拟器不需要API密钥,也不用复杂配置,只要请求指向模拟器地址(默认
http://localhost:9099),请求体格式对就没问题。
两种可行的测试方案
方案一:用Firebase Auth模拟器测试(优先选这个)
模拟器完全能搞定用户登录的测试,直接在Go测试代码里发HTTP请求就行,步骤如下:
启动模拟器
用Firebase CLI启动Auth模拟器:firebase emulators:start --only auth默认端口9099,嫌麻烦可以在
firebase.json里修改。创建测试用户(可选)
用Admin SDK在模拟器里创建测试用户(Admin SDK支持对接模拟器):import ( "context" "firebase.google.com/go/auth" "os" ) func createTestUser(ctx context.Context) (*auth.UserRecord, error) { // 告诉Admin SDK使用模拟器 os.Setenv("FIREBASE_AUTH_EMULATOR_HOST", "localhost:9099") app, err := firebase.NewApp(ctx, nil) if err != nil { return nil, err } authClient, err := app.Auth(ctx) if err != nil { return nil, err } params := (&auth.UserToCreate{}). Email("test@example.com"). EmailVerified(true). Password("test1234") return authClient.CreateUser(ctx, params) }模拟登录获取ID Token
直接发POST请求到模拟器的登录端点,API密钥随便填个值就行(模拟器不校验):import ( "bytes" "encoding/json" "net/http" ) func getEmulatorIDToken() (string, error) { loginData := map[string]interface{}{ "email": "test@example.com", "password": "test1234", "returnSecureToken": true, } body, _ := json.Marshal(loginData) resp, err := http.Post( "http://localhost:9099/v1/accounts:signInWithPassword?key=随便填", "application/json", bytes.NewBuffer(body), ) if err != nil { return "", err } defer resp.Body.Close() var result map[string]interface{} if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { return "", err } return result["idToken"].(string), nil }测试中间件
把拿到的ID Token放到请求头Authorization: Bearer <token>里,调用你的服务接口,验证中间件能否正确解析即可。
方案二:用专用测试Firebase项目测试
如果模拟器满足不了需求,用测试项目的话,不用搞邮件链接登录,直接用密码登录的REST API就行:
- 创建测试用户:和模拟器的代码逻辑一致,只是去掉
FIREBASE_AUTH_EMULATOR_HOST环境变量,使用测试项目的配置。 - 调用官方REST接口登录:需要用到测试项目的Web API密钥(在Firebase控制台项目设置中获取):
import ( "bytes" "encoding/json" "fmt" "net/http" ) func getTestProjectIDToken(apiKey string) (string, error) { loginData := map[string]interface{}{ "email": "test@example.com", "password": "test1234", "returnSecureToken": true, } body, _ := json.Marshal(loginData) url := fmt.Sprintf("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=%s", apiKey) resp, err := http.Post(url, "application/json", bytes.NewBuffer(body)) if err != nil { return "", err } defer resp.Body.Close() var result map[string]interface{} if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { return "", err } return result["idToken"].(string), nil }
额外提醒
- 大部分测试还是可以用模拟认证的,比如用Admin SDK生成自定义Token再换成ID Token,或者直接模拟中间件的解析逻辑,省得每次都连接模拟器或测试项目。
- 模拟器的Auth接口和官方完全一致,官方文档里的所有Auth REST接口都能在模拟器上使用,不用再盲目查找。
内容的提问来源于stack exchange,提问作者Yoric
相关产品推荐
相关产品推荐

