如何在Go中通过邮箱密码为现有Firebase用户获取Google OAuth2令牌
Go实现Firebase邮箱密码认证(无需服务账号)
实现原理
Firebase的邮箱密码认证基于Google Identity Toolkit的公开API完成,无需依赖服务账号密钥,认证成功后获取的ID Token可作为身份凭证直接访问Firebase数据库等资源。
具体实现步骤
- 第一步:获取Firebase项目Web API密钥
从Firebase控制台「项目设置」页面即可获取该密钥,属于项目公开配置项,无需绑定服务账号权限。 - 第二步:调用登录接口获取ID Token
直接通过HTTP请求调用认证接口完成邮箱密码校验,示例代码如下:
package main import ( "bytes" "encoding/json" "fmt" "net/http" ) // 登录请求结构体 type EmailLoginReq struct { Email string `json:"email"` Password string `json:"password"` ReturnSecureToken bool `json:"returnSecureToken"` } // 登录响应结构体 type EmailLoginResp struct { IDToken string `json:"idToken"` // 后续访问数据库的身份凭证 RefreshToken string `json:"refreshToken"` // 用于刷新过期的ID Token ExpiresIn string `json:"expiresIn"` // ID Token有效期,默认3600秒 LocalID string `json:"localId"` // 对应用户的Firebase UID Error struct { Message string `json:"message"` } `json:"error"` } // LoginWithEmailPassword 邮箱密码登录获取认证凭证 func LoginWithEmailPassword(email, password, firebaseAPIKey string) (*EmailLoginResp, error) { reqURL := fmt.Sprintf("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=%s", firebaseAPIKey) reqBody, _ := json.Marshal(EmailLoginReq{ Email: email, Password: password, ReturnSecureToken: true, }) resp, err := http.Post(reqURL, "application/json", bytes.NewBuffer(reqBody)) if err != nil { return nil, err } defer resp.Body.Close() var res EmailLoginResp if err = json.NewDecoder(resp.Body).Decode(&res); err != nil { return nil, err } if res.Error.Message != "" { return nil, fmt.Errorf("认证失败: %s", res.Error.Message) } return &res, nil }
- 第三步:使用ID Token访问数据库
访问Firebase Realtime Database或Firestore时,在请求的查询参数中带上auth参数,值为上一步获取的ID Token即可完成身份校验,示例如下(以Realtime Database为例):
// GetFirebaseDBData 用ID Token访问Realtime Database数据 func GetFirebaseDBData(dbURL, resourcePath, idToken string) (map[string]interface{}, error) { reqURL := fmt.Sprintf("%s/%s.json?auth=%s", dbURL, resourcePath, idToken) resp, err := http.Get(reqURL) if err != nil { return nil, err } defer resp.Body.Close() var data map[string]interface{} if err = json.NewDecoder(resp.Body).Decode(&data); err != nil { return nil, err } return data, nil }
注意事项
- ID Token默认有效期为1小时,过期后可使用登录接口返回的Refresh Token调用刷新接口获取新的ID Token,无需用户重新输入账号密码
- 需提前在Firebase控制台的「Auth → 登录方式」页面开启「邮箱/密码」登录开关
- 需配置对应数据库的安全规则,允许认证用户访问对应资源,否则会返回权限拒绝错误
内容的提问来源于stack exchange,提问作者0xKitsune
相关产品推荐
相关产品推荐

