使用golang-jwt验证JWT时出现signature is invalid问题求助
问题解决:golang-jwt验证JWT时提示"signature is invalid"
核心问题定位
从日志和代码可直接找到两个导致签名验证失败的原因:
- 密钥不匹配:日志显示生成Token时使用的密钥是
Indisputably-Salty-Orbit-7260-07erijgpeirgjpejgptrjgpptgjpritgpi4rtnghi,但验证中间件里硬编码的是keepmesecret,签名与验签用不同密钥必然导致验证失败。 - Token被污染:日志中接收的Token末尾带有
login字符串(如...Epvrwlogin),说明登录接口返回时把Token和额外的"login"字符串拼接了,导致解析的Token并非完整正确内容。
修复步骤
1. 统一签名密钥
将密钥抽为全局变量或配置项,确保生成与验证使用同一密钥:
// 全局统一密钥,替换为实际使用的密钥 var secretKey = "Indisputably-Salty-Orbit-7260-07erijgpeirgjpejgptrjgpptgjpritgpi4rtnghi" // 修改验证中间件的密钥使用逻辑 func validateJWT(tokenString string) (*jwt.Token, error) { return jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return []byte(secretKey), nil }) } // 修改登录接口的密钥使用逻辑 func RouteLogin(c echo.Context) error { username := c.FormValue("username") password := c.FormValue("password") if username == "admin" { if password != settings.Accounts.Admin.Password { return c.String(401, "Unauthorized") } return sendToken(c, secretKey, username) } else { accounts := settings.Accounts.GuestAccounts account, ok := accounts[username] if !ok { return c.String(404, "Not Found") } if account.Password != password { return c.String(401, "Unauthorized") } return sendToken(c, secretKey, username) } }
2. 修复登录接口的返回逻辑
原登录接口调用sendToken后未直接返回,导致后续执行了return c.String(200, "login"),把Token与"login"字符串拼接返回,需修正为直接返回sendToken的结果:
func RouteLogin(c echo.Context) error { username := c.FormValue("username") password := c.FormValue("password") if username == "admin" { if password != settings.Accounts.Admin.Password { return c.String(401, "Unauthorized") } // 直接返回Token,避免后续拼接额外内容 return sendToken(c, secretKey, username) } else { accounts := settings.Accounts.GuestAccounts account, ok := accounts[username] if !ok { return c.String(404, "Not Found") } if account.Password != password { return c.String(401, "Unauthorized") } return sendToken(c, secretKey, username) } }
3. 优化Token提取逻辑(可选)
原代码用strings.Split提取Token时未做错误处理,若Header格式错误会直接panic,建议增加校验:
func Authenticator(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { authHeader := c.Request().Header.Get("Authorization") if authHeader == "" { return c.JSON(401, map[string]interface{}{"error": "Authorization header missing"}) } parts := strings.Split(authHeader, "Bearer ") if len(parts) != 2 { return c.JSON(401, map[string]interface{}{"error": "Invalid Authorization format"}) } tokenString := parts[1] token, err := validateJWT(tokenString) if err != nil { fmt.Println(err) return c.JSON(401, map[string]interface{}{"error": "Invalid token"}) } if !token.Valid { return c.JSON(401, map[string]interface{}{"error": "Invalid token"}) } claims := token.Claims.(jwt.MapClaims) c.Set("user", claims["username"]) return next(c) } }
内容的提问来源于stack exchange,提问作者RiBi
相关产品推荐
相关产品推荐

