diff --git a/example.env b/example.env index e645c96e9c..0f9204b0d9 100644 --- a/example.env +++ b/example.env @@ -6,6 +6,7 @@ GOTRUE_JWT_EXP="3600" GOTRUE_JWT_AUD="authenticated" GOTRUE_JWT_DEFAULT_GROUP_NAME="authenticated" GOTRUE_JWT_ADMIN_ROLES="supabase_admin,service_role" +GOTRUE_JWT_ADDITIONAL_CLAIMS="email,phone,app_metadata,user_metadata,amr,is_anonymous" # Database & API connection details GOTRUE_DB_DRIVER="postgres" diff --git a/internal/api/token.go b/internal/api/token.go index cc945f2e13..3b1c992677 100644 --- a/internal/api/token.go +++ b/internal/api/token.go @@ -23,9 +23,9 @@ import ( // AccessTokenClaims is a struct thats used for JWT claims type AccessTokenClaims struct { jwt.RegisteredClaims - Email string `json:"email"` - Phone string `json:"phone"` - AppMetaData map[string]interface{} `json:"app_metadata"` + Email string `json:"email,omitempty"` + Phone string `json:"phone,omitempty"` + AppMetaData map[string]interface{} `json:"app_metadata,omitempty"` UserMetaData map[string]interface{} `json:"user_metadata"` Role string `json:"role"` AuthenticatorAssuranceLevel string `json:"aal,omitempty"` @@ -333,15 +333,27 @@ func (a *API) generateAccessToken(r *http.Request, tx *storage.Connection, user ExpiresAt: jwt.NewNumericDate(expiresAt), Issuer: config.JWT.Issuer, }, - Email: user.GetEmail(), - Phone: user.GetPhone(), - AppMetaData: user.AppMetaData, - UserMetaData: user.UserMetaData, - Role: user.Role, - SessionId: sid, - AuthenticatorAssuranceLevel: aal.String(), - AuthenticationMethodReference: amr, - IsAnonymous: user.IsAnonymous, + AuthenticatorAssuranceLevel: aal.String(), + SessionId: sid, + Role: user.Role, + } + + // add additional claims that are optional + for _, rc := range config.JWT.AdditionalClaims { + switch rc { + case "email": + claims.Email = user.GetEmail() + case "phone": + claims.Phone = user.GetPhone() + case "app_metadata": + claims.AppMetaData = user.AppMetaData + case "user_metadata": + claims.UserMetaData = user.UserMetaData + case "amr": + claims.AuthenticationMethodReference = amr + case "is_anonymous": + claims.IsAnonymous = user.IsAnonymous + } } var gotrueClaims jwt.Claims = claims diff --git a/internal/conf/configuration.go b/internal/conf/configuration.go index c4d910d991..6eaf82aa81 100644 --- a/internal/conf/configuration.go +++ b/internal/conf/configuration.go @@ -111,6 +111,7 @@ type JWTConfiguration struct { KeyID string `json:"key_id" split_words:"true"` Keys JwtKeysDecoder `json:"keys"` ValidMethods []string `json:"-"` + AdditionalClaims []string `json:"additional_claims" split_words:"true"` } type MFAFactorTypeConfiguration struct {