How to parse a JWT token with RSA in jwt-go ParseWithClaims?

huangapple go评论78阅读模式
英文:

How to parse a JWT token with RSA in jwt-go ParseWithClaims?

问题

我已经开发了以下方法,应该可以实现基于令牌的身份验证(jwt)。应该使用异步进程来生成令牌。

源代码似乎在生成签名令牌时工作正常。当使用ParseWithClaims查询令牌时,我遇到了一个问题。有人可以帮忙吗?

package controllers

import (
	"crypto/rand"
	rsaKeys "crypto/rsa"
	"fmt"

	jwtgo "github.com/dgrijalva/jwt-go"
	"github.com/gofiber/fiber"
)

func Login(c *fiber.Ctx) error {
	
	type TestClaims struct {
		HAPP string `json:"happ"`
		jwtgo.StandardClaims
	}

	currentPrivateKey, err := rsaKeys.GenerateKey(rand.Reader, 512)

	claims := TestClaims{
		"owa",
		jwtgo.StandardClaims{
			Issuer:    "test",
			ExpiresAt: 15000,
		},
	}

	token := jwtgo.NewWithClaims(jwtgo.SigningMethodRS256, claims)

	tokenSigned, err := token.SignedString(currentPrivateKey)
	if err != nil {
		fmt.Printf("Failed to sign in account %v", err)
	}

	//Issue is in this statement
	_, errTest := jwtgo.ParseWithClaims(tokenSigned, &TestClaims{"owa", jwtgo.StandardClaims{}}, func(token *jwtgo.Token) (interface{}, error) {
		return currentPrivateKey, nil
	})

	if errTest != nil {
		fmt.Printf("Error Message: %v", errTest) //Does throw error: key is of invalid type
	}

	return c.JSON(fiber.Map{
		"message": "success",
	})
}

英文:

I have developed the following method, which should enable token-based authentication (jwt). An asynchronous process should be used to generate the token.

The source code seems to work up to and including the generation of the signed token.
I encountered an issue when querying the token with ParseWithClaims. Can someone help please?

package controllers

import (
	"crypto/rand"
	rsaKeys "crypto/rsa"
	"fmt"

	jwtgo "github.com/dgrijalva/jwt-go"
	"github.com/gofiber/fiber"
)

func Login(c *fiber.Ctx) error {
	
	type TestClaims struct {
		HAPP string `json:"happ"`
		jwtgo.StandardClaims
	}

	currentPrivateKey, err := rsaKeys.GenerateKey(rand.Reader, 512)

	claims := TestClaims{
		"owa",
		jwtgo.StandardClaims{
			Issuer:    "test",
			ExpiresAt: 15000,
		},
	}

	token := jwtgo.NewWithClaims(jwtgo.SigningMethodRS256, claims)

	tokenSigned, err := token.SignedString(currentPrivateKey)
	if err != nil {
		fmt.Printf("Failed to sign in account %v", err)
	}

	//Issue is in this statement
	_, errTest := jwtgo.ParseWithClaims(tokenSigned, &TestClaims{"owa", jwtgo.StandardClaims{}}, func(token *jwtgo.Token) (interface{}, error) {
		return currentPrivateKey, nil
	})

	if errTest != nil {
		fmt.Printf("Error Message: %v", errTest) //Does throw error: key is of invalid type
	}

	return c.JSON(fiber.Map{
		"message": "success",
	})
}

答案1

得分: 3

要验证JWT,你需要使用公钥,具体来说,ParseWithClaims函数需要一个*rsa.PublicKey类型的密钥。

你可以使用PrivateKey.Public从私钥中获取公钥:

tok, err := jwtgo.ParseWithClaims(tokenSigned, &TestClaims{"owa", jwtgo.StandardClaims{}}, func(token *jwtgo.Token) (interface{}, error) {
    return currentPrivateKey.Public(), nil
})

请注意,dgrijalva/jwt-go已经不再维护。如果可以的话,请切换到社区分支golang-jwt/jwt,它包含了关键的安全修复。

英文:

To validate the JWT you need the public key, specifically ParseWithClaims expects a key of type *rsa.PublicKey.

You can get it from the private key with PrivateKey.Public:

tok, err := jwtgo.ParseWithClaims(tokenSigned, &TestClaims{"owa", jwtgo.StandardClaims{}}, func(token *jwtgo.Token) (interface{}, error) {
    return currentPrivateKey.Public(), nil
})

Please note that dgrijalva/jwt-go is unmaintained. If you can, switch to the community fork golang-jwt/jwt, which includes critical security fixes.

huangapple
  • 本文由 发表于 2021年7月22日 15:56:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/68481150.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定