...

Source file src/github.com/golang-jwt/jwt/v4/token.go

Documentation: github.com/golang-jwt/jwt/v4

     1  package jwt
     2  
     3  import (
     4  	"encoding/base64"
     5  	"encoding/json"
     6  	"strings"
     7  	"time"
     8  )
     9  
    10  // DecodePaddingAllowed will switch the codec used for decoding JWTs respectively. Note that the JWS RFC7515
    11  // states that the tokens will utilize a Base64url encoding with no padding. Unfortunately, some implementations
    12  // of JWT are producing non-standard tokens, and thus require support for decoding. Note that this is a global
    13  // variable, and updating it will change the behavior on a package level, and is also NOT go-routine safe.
    14  // To use the non-recommended decoding, set this boolean to `true` prior to using this package.
    15  var DecodePaddingAllowed bool
    16  
    17  // DecodeStrict will switch the codec used for decoding JWTs into strict mode.
    18  // In this mode, the decoder requires that trailing padding bits are zero, as described in RFC 4648 section 3.5.
    19  // Note that this is a global variable, and updating it will change the behavior on a package level, and is also NOT go-routine safe.
    20  // To use strict decoding, set this boolean to `true` prior to using this package.
    21  var DecodeStrict bool
    22  
    23  // TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time).
    24  // You can override it to use another time value.  This is useful for testing or if your
    25  // server uses a different time zone than your tokens.
    26  var TimeFunc = time.Now
    27  
    28  // Keyfunc will be used by the Parse methods as a callback function to supply
    29  // the key for verification.  The function receives the parsed,
    30  // but unverified Token.  This allows you to use properties in the
    31  // Header of the token (such as `kid`) to identify which key to use.
    32  type Keyfunc func(*Token) (interface{}, error)
    33  
    34  // Token represents a JWT Token.  Different fields will be used depending on whether you're
    35  // creating or parsing/verifying a token.
    36  type Token struct {
    37  	Raw       string                 // The raw token.  Populated when you Parse a token
    38  	Method    SigningMethod          // The signing method used or to be used
    39  	Header    map[string]interface{} // The first segment of the token
    40  	Claims    Claims                 // The second segment of the token
    41  	Signature string                 // The third segment of the token.  Populated when you Parse a token
    42  	Valid     bool                   // Is the token valid?  Populated when you Parse/Verify a token
    43  }
    44  
    45  // New creates a new Token with the specified signing method and an empty map of claims.
    46  func New(method SigningMethod) *Token {
    47  	return NewWithClaims(method, MapClaims{})
    48  }
    49  
    50  // NewWithClaims creates a new Token with the specified signing method and claims.
    51  func NewWithClaims(method SigningMethod, claims Claims) *Token {
    52  	return &Token{
    53  		Header: map[string]interface{}{
    54  			"typ": "JWT",
    55  			"alg": method.Alg(),
    56  		},
    57  		Claims: claims,
    58  		Method: method,
    59  	}
    60  }
    61  
    62  // SignedString creates and returns a complete, signed JWT.
    63  // The token is signed using the SigningMethod specified in the token.
    64  func (t *Token) SignedString(key interface{}) (string, error) {
    65  	var sig, sstr string
    66  	var err error
    67  	if sstr, err = t.SigningString(); err != nil {
    68  		return "", err
    69  	}
    70  	if sig, err = t.Method.Sign(sstr, key); err != nil {
    71  		return "", err
    72  	}
    73  	return strings.Join([]string{sstr, sig}, "."), nil
    74  }
    75  
    76  // SigningString generates the signing string.  This is the
    77  // most expensive part of the whole deal.  Unless you
    78  // need this for something special, just go straight for
    79  // the SignedString.
    80  func (t *Token) SigningString() (string, error) {
    81  	var err error
    82  	var jsonValue []byte
    83  
    84  	if jsonValue, err = json.Marshal(t.Header); err != nil {
    85  		return "", err
    86  	}
    87  	header := EncodeSegment(jsonValue)
    88  
    89  	if jsonValue, err = json.Marshal(t.Claims); err != nil {
    90  		return "", err
    91  	}
    92  	claim := EncodeSegment(jsonValue)
    93  
    94  	return strings.Join([]string{header, claim}, "."), nil
    95  }
    96  
    97  // Parse parses, validates, verifies the signature and returns the parsed token.
    98  // keyFunc will receive the parsed token and should return the cryptographic key
    99  // for verifying the signature.
   100  // The caller is strongly encouraged to set the WithValidMethods option to
   101  // validate the 'alg' claim in the token matches the expected algorithm.
   102  // For more details about the importance of validating the 'alg' claim,
   103  // see https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
   104  func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) {
   105  	return NewParser(options...).Parse(tokenString, keyFunc)
   106  }
   107  
   108  // ParseWithClaims is a shortcut for NewParser().ParseWithClaims().
   109  //
   110  // Note: If you provide a custom claim implementation that embeds one of the standard claims (such as RegisteredClaims),
   111  // make sure that a) you either embed a non-pointer version of the claims or b) if you are using a pointer, allocate the
   112  // proper memory for it before passing in the overall claims, otherwise you might run into a panic.
   113  func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) {
   114  	return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc)
   115  }
   116  
   117  // EncodeSegment encodes a JWT specific base64url encoding with padding stripped
   118  //
   119  // Deprecated: In a future release, we will demote this function to a non-exported function, since it
   120  // should only be used internally
   121  func EncodeSegment(seg []byte) string {
   122  	return base64.RawURLEncoding.EncodeToString(seg)
   123  }
   124  
   125  // DecodeSegment decodes a JWT specific base64url encoding with padding stripped
   126  //
   127  // Deprecated: In a future release, we will demote this function to a non-exported function, since it
   128  // should only be used internally
   129  func DecodeSegment(seg string) ([]byte, error) {
   130  	encoding := base64.RawURLEncoding
   131  
   132  	if DecodePaddingAllowed {
   133  		if l := len(seg) % 4; l > 0 {
   134  			seg += strings.Repeat("=", 4-l)
   135  		}
   136  		encoding = base64.URLEncoding
   137  	}
   138  
   139  	if DecodeStrict {
   140  		encoding = encoding.Strict()
   141  	}
   142  	return encoding.DecodeString(seg)
   143  }
   144  

View as plain text