【问题标题】:JWT doesn't validate the token receivedJWT 不验证收到的令牌
【发布时间】:2020-05-14 09:21:01
【问题描述】:

我有一个注册器端点和一个使用 JWT 响应的登录端点

但是当接收到这个 JWT 时,这个过程会抛出 INVALID TOKEN

func ValidarToken(w http.ResponseWriter, r *http.Request) bool {

token, err := request.ParseFromRequestWithClaims(r, request.OAuth2Extractor, &models.Claim{}, func(token *jwt.Token) (interface{}, error){
        return VerifyKey, nil
})

if err != nil {
    switch err.(type) {
    case *jwt.ValidationError:
            vErr := err.(*jwt.ValidationError)
            switch vErr.Errors {
                case jwt.ValidationErrorExpired:
                    http.Error(w, "Su token ha expirado "+err.Error(),http.StatusUnauthorized)
                case jwt.ValidationErrorSignatureInvalid:
                    http.Error(w, "La firma del token no coincide "+err.Error(),http.StatusUnauthorized)
                default:
                    http.Error(w, "Su token no es válido "+err.Error(),http.StatusUnauthorized)
            }
    default:
        http.Error(w, "Su token no es válido "+err.Error(),http.StatusUnauthorized)
    }
    return false
}

我已经阅读了很多文档,但我不明白为什么我生成的同一个令牌,然后它就不能被同一个 App 识别

谢谢

更新:

这是我的生成 JWT 代码

func GeneroJWT(t models.Usuario) (string, error) {

    leoClaves()

    payload := jwt.MapClaims{
           "email": t.Email,
           "nombre": t.Nombre,
           "apellidos": t.Apellidos,
           "fecha_nacimiento": t.FechaNacimiento,
           "biografia": t.Biografia,
           "ubicacion": t.Ubicacion,
           "sitioweb": t.SitioWeb,
           "exp": time.Now().Add(time.Hour * 24).Unix(),
    }

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, payload)

    tokenStr, err := token.SignedString(SignKey)

    if err != nil {
        return tokenStr, err
    }
    return tokenStr,nil
}

【问题讨论】:

  • 请提供更多信息(从您的问题中不清楚问题是您的验证码还是其他问题;例如令牌创建、将其添加到标头的例程等)。一个好的第一步是在收到令牌时手动检查令牌。为此,将tokStr, err := request.OAuth2Extractor.ExtractToken(r) 添加到ValidarToken 的顶部(将结果转储到您的日志或控制台)并检查这是否成功并且tokStr 是完整的令牌(实际上使用this tool 之类的东西来查看它是否是, 有效)。
  • 嗨,英国人,令牌很好。我有相同的字节,但是当我使用 PrivateKey 处理这个令牌时,结果是 ERR,现在我使用这个 tkn,err := jwt.ParseWithClaims (reqToken, Claims, func(token *jwt.Token) (interface{}, error) { return jwtKey, nil }) 我也有同样的错误
  • 我的理解是你用私钥创建令牌,然后用公钥验证? (至少这就是它与 JWT 一起工作的方式)。无论哪种方式,您都没有为某人提供足够的信息来诊断您的问题 - 放置创建令牌然后立即尝试验证它的代码将有助于专注于您的问题(正如您所说的那样,这与令牌的方式无关已沟通)
  • 嗨,英国人...请查看我编辑的详细信息,谢谢
  • token := jwt.NewWithClaims(jwt.SigningMethodHS256, payload) 创建一个带有 HS256 签名的令牌(请参阅this question)。如果要使用证书,则需要使用 SigningMethodRS256(或 SigningMethodES256)并进行一些更改以准备证书以供使用。 example

标签: go


【解决方案1】:

我用这个库在 Go 中签署 JWT:github.com/dgrijalva/jwt-go,然后我像这样检查它:

		reqToken := r.Header.Get("Authorization")

		splitToken := strings.Split(reqToken, "Bearer")
		if len(splitToken) != 2 {
			w.WriteHeader(http.StatusUnauthorized)
			fmt.Fprintln(w, "No se ha proporcionado el token")
			return
		}

		reqToken = strings.TrimSpace(splitToken[1])

		claims := &Claims{}

		tkn, err := jwt.ParseWithClaims(reqToken, claims, func(token *jwt.Token) (interface{}, error) {
			return jwtKey, nil
		})

		if err != nil {
			if err == jwt.ErrSignatureInvalid {
				w.WriteHeader(http.StatusUnauthorized)
				fmt.Fprintln(w, "No autenticado")
				return
			}
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintln(w, "No autenticado")
			return
		}
		if !tkn.Valid {
			w.WriteHeader(http.StatusUnauthorized)
			return
		}

		next.ServeHTTP(w, r)

希望对你有所帮助。

【讨论】:

  • 嗨费尔南多,谢谢你的回答,但我仍然有同样的问题......你的代码......看,我的私钥和公钥是使用 OpenSSL 库生成的......在 base64 编码中。
【解决方案2】:

在这种情况下,问题(根据 cmets)是使用 RSA 证书作为机密生成 HS256 令牌。 HSA256 算法是对称的(有关更多信息,请参阅this question),因此要使用它进行解码,您需要传入与创建令牌相同的秘密(在这种情况下,证书作为密钥传入,但库是将其视为 []byte 而不是处理证书)。

如果您想使用非对称加密(使用私钥加密;使用公钥验证),则应使用另一种算法(例如 RS256)。 Example.

【讨论】:

    猜你喜欢
    • 2019-06-23
    • 2017-07-27
    • 2019-10-20
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 2018-10-16
    • 2019-11-01
    相关资源
    最近更新 更多