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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:23:18