upgraded to jwt/v5
This commit is contained in:
+8
-10
@@ -6,7 +6,7 @@ import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"github.com/spf13/cast"
|
||||
"golang.org/x/oauth2"
|
||||
@@ -138,19 +138,17 @@ func (p *Apple) parseAndVerifyIdToken(idToken string) (jwt.MapClaims, error) {
|
||||
|
||||
// validate common claims per https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/verifying_a_user#3383769
|
||||
// ---
|
||||
err = claims.Valid() // exp, iat, etc.
|
||||
jwtValidator := jwt.NewValidator(
|
||||
jwt.WithExpirationRequired(),
|
||||
jwt.WithIssuedAt(),
|
||||
jwt.WithIssuer("https://appleid.apple.com"),
|
||||
jwt.WithAudience(p.clientId),
|
||||
)
|
||||
err = jwtValidator.Validate(claims)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !claims.VerifyIssuer("https://appleid.apple.com", true) {
|
||||
return nil, errors.New("iss must be https://appleid.apple.com")
|
||||
}
|
||||
|
||||
if !claims.VerifyAudience(p.clientId, true) {
|
||||
return nil, errors.New("aud must be the developer's client_id")
|
||||
}
|
||||
|
||||
// validate id_token signature
|
||||
//
|
||||
// note: this step could be technically considered optional because we trust
|
||||
|
||||
+10
-9
@@ -12,7 +12,8 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"github.com/spf13/cast"
|
||||
"golang.org/x/oauth2"
|
||||
@@ -128,24 +129,24 @@ func (p *OIDC) parseIdToken(token *oauth2.Token) (jwt.MapClaims, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate common claims like exp, iat, etc.
|
||||
err = claims.Valid()
|
||||
// validate common claims
|
||||
jwtValidator := jwt.NewValidator(
|
||||
jwt.WithIssuedAt(),
|
||||
jwt.WithAudience(p.clientId),
|
||||
)
|
||||
err = jwtValidator.Validate(claims)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate aud
|
||||
if !claims.VerifyAudience(p.clientId, true) {
|
||||
return nil, errors.New("aud must be the developer's client_id")
|
||||
}
|
||||
|
||||
// validate iss (if "issuers" extra config is set)
|
||||
issuers := cast.ToStringSlice(p.Extra()["issuers"])
|
||||
if len(issuers) > 0 {
|
||||
var isIssValid bool
|
||||
claimIssuer, _ := claims.GetIssuer()
|
||||
|
||||
for _, issuer := range issuers {
|
||||
if claims.VerifyIssuer(issuer, true) {
|
||||
if security.Equal(claimIssuer, issuer) {
|
||||
isIssValid = true
|
||||
break
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@ import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
// @todo update to v5
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
// ParseUnverifiedJWT parses JWT and returns its claims
|
||||
@@ -19,7 +18,7 @@ func ParseUnverifiedJWT(token string) (jwt.MapClaims, error) {
|
||||
_, _, err := parser.ParseUnverified(token, claims)
|
||||
|
||||
if err == nil {
|
||||
err = claims.Valid()
|
||||
err = jwt.NewValidator(jwt.WithIssuedAt()).Validate(claims)
|
||||
}
|
||||
|
||||
return claims, err
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ func TestParseUnverifiedJWT(t *testing.T) {
|
||||
}
|
||||
|
||||
// properly formatted JWT with INVALID claims
|
||||
// {"name": "test", "exp": 1516239022}
|
||||
// {"name": "test", "exp":1516239022}
|
||||
result2, err2 := security.ParseUnverifiedJWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGVzdCIsImV4cCI6MTUxNjIzOTAyMn0.xYHirwESfSEW3Cq2BL47CEASvD_p_ps3QCA54XtNktU")
|
||||
if err2 == nil {
|
||||
t.Error("Expected error got nil")
|
||||
@@ -30,14 +30,24 @@ func TestParseUnverifiedJWT(t *testing.T) {
|
||||
t.Errorf("Expected to have 2 claims, got %v", result2)
|
||||
}
|
||||
|
||||
// properly formatted JWT with VALID claims
|
||||
// properly formatted JWT with VALID claims (missing exp)
|
||||
// {"name": "test"}
|
||||
result3, err3 := security.ParseUnverifiedJWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGVzdCJ9.ml0QsTms3K9wMygTu41ZhKlTyjmW9zHQtoS8FUsCCjU")
|
||||
if err3 != nil {
|
||||
t.Error("Expected nil, got", err3)
|
||||
}
|
||||
if len(result3) != 1 || result3["name"] != "test" {
|
||||
t.Errorf("Expected to have 2 claims, got %v", result3)
|
||||
t.Errorf("Expected to have 1 claim, got %v", result3)
|
||||
}
|
||||
|
||||
// properly formatted JWT with VALID claims (valid exp)
|
||||
// {"name": "test", "exp": 2208985261}
|
||||
result4, err4 := security.ParseUnverifiedJWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGVzdCIsImV4cCI6MjIwODk4NTI2MX0._0KQu60hYNx5wkBIpEaoX35shXRicb0X_0VdWKWb-3k")
|
||||
if err4 != nil {
|
||||
t.Error("Expected nil, got", err4)
|
||||
}
|
||||
if len(result4) != 2 || result4["name"] != "test" {
|
||||
t.Errorf("Expected to have 2 claims, got %v", result4)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user