Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ParseWithClaims fails from json.NewDecoder #336

Answered by mfridman
Aner-Git asked this question in Q&A
Discussion options

An error occurs for this simple code:

import (
	"testing"
	"github.com/golang-jwt/jwt/v5"
	"github.com/stretchr/testify/assert"
)
type cc struct {
	Foo string `json:"foo"`
	jwt.RegisteredClaims
}
func TestParseWClaims(t *testing.T) {
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, cc{Foo: "value"})
	// Sign and get the complete encoded token as a string using the secret
	tokenString, err := token.SignedString([]byte("xxxx"))
	assert.Nil(t, err, "Sign failed")
	parser := &jwt.Parser{}
	var c cc
	ttoken, err := parser.ParseWithClaims(tokenString, c, func(t *jwt.Token) (any, error) { return []byte("xxxx"), nil })
	t.Logf("%+v", ttoken.Claims)
	assert.Nil(t, err, "Parse claims")
	assert.Equal(t, ttoken.Claims.(cc).Foo, "value")
}

Produces:
&fmt.wrapErrors{msg:"token is malformed: could not JSON decode claim: json: cannot unmarshal object into Go value of type jwt.Claims", errs:[]error{(*errors.errorString)(0xc0000588d0), (*json.UnmarshalTypeError)(0xc0000743c0)}}

go version
go version go1.20.4 linux/amd64

The error occurs calling Decode of a json decoder. Here is a simplified example of the call stack in the code.
Note the func call which 'simulates' the call to ParseWithClaims.

type cc struct {
	Foo string `json:"foo"`
	jwt.RegisteredClaims
}
func TestJsonDec(t *testing.T) {
	bs := []byte(`{"Foo":"value"}`)
	func(claim jwt.Claims) {
		c := claim
		dec := json.NewDecoder(bytes.NewBuffer(bs))
		e := dec.Decode(&c)
		assert.Nil(t, e)
	}(c)
}

Apart from using the map not clear how to solve this.

You must be logged in to vote

Pass the memory address of c, e.g.,

ttoken, err := parser.ParseWithClaims(tokenString, &c <--- here

and then assert Claims to your type (*cc) in this case, e.g.,

v, ok := ttoken.Claims.(*cc)
if ok {
 fmt.Println(v.Foo)
 // value
}

There is an example of custom claims here if it helps:

jwt/http_example_test.go

Lines 101 to 109 in 8aa5d6c

token, err := jwt.ParseWithClaims(tokenString, &CustomClaimsExample{}, func(token *jwt.Token) (interface{}, error) {
// since we only use the one private key to sign the tokens,
// we also only use its public counter part to verify
return verifyKey, nil
})
fatal(err)
claims := token.Claims.(*CustomClaimsEx...

Replies: 4 comments

Comment options

Pass the memory address of c, e.g.,

ttoken, err := parser.ParseWithClaims(tokenString, &c <--- here

and then assert Claims to your type (*cc) in this case, e.g.,

v, ok := ttoken.Claims.(*cc)
if ok {
 fmt.Println(v.Foo)
 // value
}

There is an example of custom claims here if it helps:

jwt/http_example_test.go

Lines 101 to 109 in 8aa5d6c

token, err := jwt.ParseWithClaims(tokenString, &CustomClaimsExample{}, func(token *jwt.Token) (interface{}, error) {
// since we only use the one private key to sign the tokens,
// we also only use its public counter part to verify
return verifyKey, nil
})
fatal(err)
claims := token.Claims.(*CustomClaimsExample)
fmt.Println(claims.CustomerInfo.Name)
You must be logged in to vote
0 replies
Answer selected by oxisto
Comment options

ttoken, err := jwt.ParseWithClaims(tokenString, &c, func(t *jwt.Token) (any, error) { return []byte("xxxx"), nil })

I get

jwt_test.go:63: &{Foo:value RegisteredClaims:{Issuer: Subject: Audience:[] ExpiresAt:<nil> NotBefore:<nil> IssuedAt:<nil> ID:}}
panic: interface conversion: jwt.Claims is *auth.cc, not auth.cc [recovered]
	panic: interface conversion: jwt.Claims is *auth.cc, not auth.cc
You must be logged in to vote
0 replies
Comment options

A few suggestions,

  1. assert for the type so you don't get panic (comma okay):
- assert.Equal(t, ttoken.Claims.(cc).Foo, "value")
+ customClaims, ok := ttoken.Claims.(cc)
  1. the type you're asserting for should be *cc and not cc
 ttoken.Claims.(*cc)
You must be logged in to vote
0 replies
Comment options

Moving this to the Q&A discussion.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
Converted from issue

This discussion was converted from issue #333 on August 14, 2023 19:00.

AltStyle によって変換されたページ (->オリジナル) /