package jwtimport ()// Claims must just have a Valid method that determines// if the token is invalid for any supported reasontypeClaimsinterface {Valid() error}// RegisteredClaims are a structured version of the JWT Claims Set,// restricted to Registered Claim Names, as referenced at// https://datatracker.ietf.org/doc/html/rfc7519#section-4.1//// This type can be used on its own, but then additional private and// public claims embedded in the JWT will not be parsed. The typical usecase// therefore is to embedded this in a user-defined claim type.//// See examples for how to use this with your own claim types.typeRegisteredClaimsstruct {// the `iss` (Issuer) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1 Issuer string`json:"iss,omitempty"`// the `sub` (Subject) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2 Subject string`json:"sub,omitempty"`// the `aud` (Audience) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3 Audience ClaimStrings`json:"aud,omitempty"`// the `exp` (Expiration Time) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4 ExpiresAt *NumericDate`json:"exp,omitempty"`// the `nbf` (Not Before) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5 NotBefore *NumericDate`json:"nbf,omitempty"`// the `iat` (Issued At) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6 IssuedAt *NumericDate`json:"iat,omitempty"`// the `jti` (JWT ID) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7 ID string`json:"jti,omitempty"`}// Valid validates time based claims "exp, iat, nbf".// There is no accounting for clock skew.// As well, if any of the above claims are not in the token, it will still// be considered a valid claim.func ( RegisteredClaims) () error { := new(ValidationError) := TimeFunc()// The claims below are optional, by default, so if they are set to the // default value in Go, let's not fail the verification for them.if !.VerifyExpiresAt(, false) { := .Sub(.ExpiresAt.Time) .Inner = fmt.Errorf("%s by %s", ErrTokenExpired, ) .Errors |= ValidationErrorExpired }if !.VerifyIssuedAt(, false) { .Inner = ErrTokenUsedBeforeIssued .Errors |= ValidationErrorIssuedAt }if !.VerifyNotBefore(, false) { .Inner = ErrTokenNotValidYet .Errors |= ValidationErrorNotValidYet }if .valid() {returnnil }return}// VerifyAudience compares the aud claim against cmp.// If required is false, this method will return true if the value matches or is unsetfunc ( *RegisteredClaims) ( string, bool) bool {returnverifyAud(.Audience, , )}// VerifyExpiresAt compares the exp claim against cmp (cmp < exp).// If req is false, it will return true, if exp is unset.func ( *RegisteredClaims) ( time.Time, bool) bool {if .ExpiresAt == nil {returnverifyExp(nil, , ) }returnverifyExp(&.ExpiresAt.Time, , )}// VerifyIssuedAt compares the iat claim against cmp (cmp >= iat).// If req is false, it will return true, if iat is unset.func ( *RegisteredClaims) ( time.Time, bool) bool {if .IssuedAt == nil {returnverifyIat(nil, , ) }returnverifyIat(&.IssuedAt.Time, , )}// VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf).// If req is false, it will return true, if nbf is unset.func ( *RegisteredClaims) ( time.Time, bool) bool {if .NotBefore == nil {returnverifyNbf(nil, , ) }returnverifyNbf(&.NotBefore.Time, , )}// VerifyIssuer compares the iss claim against cmp.// If required is false, this method will return true if the value matches or is unsetfunc ( *RegisteredClaims) ( string, bool) bool {returnverifyIss(.Issuer, , )}// StandardClaims are a structured version of the JWT Claims Set, as referenced at// https://datatracker.ietf.org/doc/html/rfc7519#section-4. They do not follow the// specification exactly, since they were based on an earlier draft of the// specification and not updated. The main difference is that they only// support integer-based date fields and singular audiences. This might lead to// incompatibilities with other JWT implementations. The use of this is discouraged, instead// the newer RegisteredClaims struct should be used.//// Deprecated: Use RegisteredClaims instead for a forward-compatible way to access registered claims in a struct.typeStandardClaimsstruct { Audience string`json:"aud,omitempty"` ExpiresAt int64`json:"exp,omitempty"` Id string`json:"jti,omitempty"` IssuedAt int64`json:"iat,omitempty"` Issuer string`json:"iss,omitempty"` NotBefore int64`json:"nbf,omitempty"` Subject string`json:"sub,omitempty"`}// Valid validates time based claims "exp, iat, nbf". There is no accounting for clock skew.// As well, if any of the above claims are not in the token, it will still// be considered a valid claim.func ( StandardClaims) () error { := new(ValidationError) := TimeFunc().Unix()// The claims below are optional, by default, so if they are set to the // default value in Go, let's not fail the verification for them.if !.VerifyExpiresAt(, false) { := time.Unix(, 0).Sub(time.Unix(.ExpiresAt, 0)) .Inner = fmt.Errorf("%s by %s", ErrTokenExpired, ) .Errors |= ValidationErrorExpired }if !.VerifyIssuedAt(, false) { .Inner = ErrTokenUsedBeforeIssued .Errors |= ValidationErrorIssuedAt }if !.VerifyNotBefore(, false) { .Inner = ErrTokenNotValidYet .Errors |= ValidationErrorNotValidYet }if .valid() {returnnil }return}// VerifyAudience compares the aud claim against cmp.// If required is false, this method will return true if the value matches or is unsetfunc ( *StandardClaims) ( string, bool) bool {returnverifyAud([]string{.Audience}, , )}// VerifyExpiresAt compares the exp claim against cmp (cmp < exp).// If req is false, it will return true, if exp is unset.func ( *StandardClaims) ( int64, bool) bool {if .ExpiresAt == 0 {returnverifyExp(nil, time.Unix(, 0), ) } := time.Unix(.ExpiresAt, 0)returnverifyExp(&, time.Unix(, 0), )}// VerifyIssuedAt compares the iat claim against cmp (cmp >= iat).// If req is false, it will return true, if iat is unset.func ( *StandardClaims) ( int64, bool) bool {if .IssuedAt == 0 {returnverifyIat(nil, time.Unix(, 0), ) } := time.Unix(.IssuedAt, 0)returnverifyIat(&, time.Unix(, 0), )}// VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf).// If req is false, it will return true, if nbf is unset.func ( *StandardClaims) ( int64, bool) bool {if .NotBefore == 0 {returnverifyNbf(nil, time.Unix(, 0), ) } := time.Unix(.NotBefore, 0)returnverifyNbf(&, time.Unix(, 0), )}// VerifyIssuer compares the iss claim against cmp.// If required is false, this method will return true if the value matches or is unsetfunc ( *StandardClaims) ( string, bool) bool {returnverifyIss(.Issuer, , )}// ----- helpersfunc verifyAud( []string, string, bool) bool {iflen() == 0 {return ! }// use a var here to keep constant time compare when looping over a number of claims := falsevarstringfor , := range {ifsubtle.ConstantTimeCompare([]byte(), []byte()) != 0 { = true } = + }// case where "" is sent in one or many aud claimsiflen() == 0 {return ! }return}func verifyExp( *time.Time, time.Time, bool) bool {if == nil {return ! }return .Before(*)}func verifyIat( *time.Time, time.Time, bool) bool {if == nil {return ! }return .After(*) || .Equal(*)}func verifyNbf( *time.Time, time.Time, bool) bool {if == nil {return ! }return .After(*) || .Equal(*)}func verifyIss( string, string, bool) bool {if == "" {return ! }returnsubtle.ConstantTimeCompare([]byte(), []byte()) != 0}
The pages are generated with Goldsv0.6.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.