-
Notifications
You must be signed in to change notification settings - Fork 347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug(token): Interface includes constraint elements, can only be used in type parameters #401
Comments
Can you give us some more context where this error should occur? The type of VerificationKey is intentionally set to either |
It's not clear if this is a From the test results of the current definition, Or Alternatively, you can use the specified type at switch have := got.(type) {
case VerificationKeySet[crypto.PublicKey]:
if len(have.Keys) == 0 {
return token, newError("keyfunc returned empty verification key set", ErrTokenUnverifiable)
}
// Iterate through keys and verify signature, skipping the rest when a match is found.
// Return the last error if no match is found.
for _, key := range have.Keys {
if err = token.Method.Verify(text, token.Signature, key); err == nil {
break
}
}
case VerificationKeySet[[]uint8]:
// Do something with []uint8 here
default:
err = token.Method.Verify(text, token.Signature, have)
} But type VerificationKeySet[T VerificationKey] struct {
Keys []T
} The associated tests |
Ok I am beginning to understand your issue... I can finally reproduce this in my IntelliJ ultimate. This is actually a bug in the IDE it seems. The following example works perfectly in VScode or directly using package main
import (
"fmt"
"github.com/golang-jwt/jwt/v5"
)
func main() {
var key1 = []uint8{1, 2, 3, 4}
var key2 = []uint8{2, 3, 4, 5}
// create a token
t := jwt.New(jwt.SigningMethodHS256)
token, _ := t.SignedString(key1)
var set jwt.VerificationKeySet = jwt.VerificationKeySet{
Keys: []jwt.VerificationKey{
key1, key2,
},
}
t, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
return set, nil
})
if err == nil {
fmt.Printf("Yay %s!\n", t.Method.Alg())
}
} This will print "Yay HS256!" on your console after But I am also seeing this error if I open this in IntelliJ... |
This seems to be a very annoying and old bug in Goland... https://youtrack.jetbrains.com/issue/GO-15406/False-positive-Interface-includes-constraint-elements-can-only-be-used-in-type-parameters |
Again, the following code: package main
import (
"fmt"
"github.com/golang-jwt/jwt/v5"
)
func main() {
var key1 = []uint8{1, 2, 3, 4}
var key2 = []uint8{2, 3, 4, 5}
// create a token
t := jwt.New(jwt.SigningMethodHS256)
token, _ := t.SignedString(key1)
var set jwt.VerificationKeySet = jwt.VerificationKeySet{
Keys: []jwt.VerificationKey{
key1, key2,
},
}
t, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
return set, nil
})
if err == nil {
fmt.Printf("Yay %s!\n", t.Method.Alg())
}
} The above code, if you remove if remove .\token.go:24:9: cannot use type VerificationKey outside a type constraint: interface contains type constraints It looks like I'll try asking the go developers tomorrow. |
Which version of Go are you using? If I run |
same as go1.22.5 // before change:
// VerificationKey represents a public or secret key for verifying a token's signature.
type VerificationKey interface {
crypto.PublicKey | []uint8
}
// change for check test:
// VerificationKey represents a public or secret key for verifying a token's signature.
type VerificationKey interface {
[]uint8
} If you do that, it won't pass type checking with |
@mfridman can you help here? I am getting confused and I cannot see any issue with the code that we have… |
Correct, because it would no longer would be a constraint-type. Iirc GoLand doesn't use the standard gopls (Go language server) and uses their hand-rolled one. So the linter is probably getting tripped up. But to your point there's two way to represent this: version 1type VerificationKeySet[T VerificationKey] struct {
Keys []T
} or version 2type VerificationKeySet struct {
Keys []VerificationKey
} The first version uses a generic type parameter I think what you're proposing is the first version, but it wouldn't be using I'm not proposing we change this, and I don't think there's anything to do since it would be a breaking change. But afaik both versions are valid, albeit version one is probably the more "idiomatic" way of doing it. |
Going to close this issue for now, I don't think there's anything to change here. But if you have further thoughts feel free to continue the discussion. |
@mfridman sure, golang/go#68710 Doesn't look like it's going to come back anytime soon. |
@godcong but I'm genuinely curious if one option is favored over the other (#401 (comment)). Both produce compilable Go code so it's a bit puzzling. GoLand reporting an error is a wholly different problem I think. |
the
crypto.PublicKey
is defined as any, although I don't know why it compiles.But the type checking does throw an exception
VerificationKeySet
should also be changed toHowever, since
any
exists, this doesn't seem to make any sense.Finally, I changed it to this.
The text was updated successfully, but these errors were encountered: