GAE Go服务验证Firebase JWT时出现base64非法数据错误
问题根源与修复方案
这个问题的核心原因非常清晰——你在解析Authorization请求头时,没有处理**Bearer后面的空格**,导致传入Firebase验证函数的token字符串开头多了一个无效的空格字符,这直接触发了base64解码失败(空格不属于Base64的合法字符集)。
具体分析你的代码问题
看这段获取token的逻辑:
reqToken := r.Header.Get("Authorization") splitToken := strings.Split(reqToken, "Bearer") reqToken = splitToken[1]
当请求头格式为Authorization: Bearer <你的token>时,strings.Split(reqToken, "Bearer")会把字符串拆成两个元素:["", " <你的token>"]——第二个元素的开头是一个空格。你打印token时可能没注意到这个空格(控制台输出可能自动换行或忽略前导空白),但Firebase的验证函数会严格解析每一个字符,因此抛出了illegal base64 data at input byte 0的错误。
修复方案
推荐两种可靠的修复方式,同时加入格式校验避免程序panic:
方式1:使用strings.TrimSpace配合精准拆分
func (ma *myapp) SomeHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") reqToken := r.Header.Get("Authorization") // 按"Bearer "(带空格)拆分,确保拆分后token部分的格式正确 splitToken := strings.Split(reqToken, "Bearer ") if len(splitToken) != 2 { http.Error(w, "Invalid Authorization header format", http.StatusUnauthorized) return } // 去除token前后的所有空白字符(包括开头的空格) cleanToken := strings.TrimSpace(splitToken[1]) // 传入清理后的token进行验证 token, err := lib.VerifyIDToken(ma.fbapp, cleanToken) if err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) return } enc := json.NewEncoder(w) err := enc.Encode(SomeData) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }
方式2:使用strings.TrimPrefix更简洁处理
func (ma *myapp) SomeHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") reqToken := r.Header.Get("Authorization") const bearerPrefix = "Bearer " // 先检查请求头是否符合前缀要求 if !strings.HasPrefix(reqToken, bearerPrefix) { http.Error(w, "Missing or invalid Bearer token", http.StatusUnauthorized) return } // 截取前缀后的部分并清理空白 cleanToken := strings.TrimSpace(reqToken[len(bearerPrefix):]) token, err := lib.VerifyIDToken(ma.fbapp, cleanToken) if err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) return } enc := json.NewEncoder(w) err := enc.Encode(SomeData) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }
额外优化建议
你的VerifyIDToken函数目前使用log.Fatalf会直接终止程序,这在HTTP服务中是非常危险的——单个无效请求就会导致服务崩溃。建议修改为返回错误,让handler处理并返回合适的HTTP响应:
func VerifyIDToken(app *firebase.App, idToken string) (*auth.Token, error) { client, err := app.Auth(context.Background()) if err != nil { return nil, fmt.Errorf("failed to get Auth client: %w", err) } token, err := client.VerifyIDToken(idToken) if err != nil { return nil, fmt.Errorf("failed to verify ID token: %w", err) } return token, nil }
内容的提问来源于stack exchange,提问作者cbll
相关产品推荐
相关产品推荐

