go-micro.dev/v5@v5.12.0/auth/jwt/token/jwt.go (about) 1 package token 2 3 import ( 4 "encoding/base64" 5 "time" 6 7 "github.com/dgrijalva/jwt-go" 8 "go-micro.dev/v5/auth" 9 ) 10 11 // authClaims to be encoded in the JWT. 12 type authClaims struct { 13 Type string `json:"type"` 14 Scopes []string `json:"scopes"` 15 Metadata map[string]string `json:"metadata"` 16 17 jwt.StandardClaims 18 } 19 20 // JWT implementation of token provider. 21 type JWT struct { 22 opts Options 23 } 24 25 // New returns an initialized basic provider. 26 func New(opts ...Option) Provider { 27 return &JWT{ 28 opts: NewOptions(opts...), 29 } 30 } 31 32 // Generate a new JWT. 33 func (j *JWT) Generate(acc *auth.Account, opts ...GenerateOption) (*Token, error) { 34 // decode the private key 35 priv, err := base64.StdEncoding.DecodeString(j.opts.PrivateKey) 36 if err != nil { 37 return nil, err 38 } 39 40 // parse the private key 41 key, err := jwt.ParseRSAPrivateKeyFromPEM(priv) 42 if err != nil { 43 return nil, ErrEncodingToken 44 } 45 46 // parse the options 47 options := NewGenerateOptions(opts...) 48 49 // generate the JWT 50 expiry := time.Now().Add(options.Expiry) 51 t := jwt.NewWithClaims(jwt.SigningMethodRS256, authClaims{ 52 acc.Type, acc.Scopes, acc.Metadata, jwt.StandardClaims{ 53 Subject: acc.ID, 54 Issuer: acc.Issuer, 55 ExpiresAt: expiry.Unix(), 56 }, 57 }) 58 tok, err := t.SignedString(key) 59 if err != nil { 60 return nil, err 61 } 62 63 // return the token 64 return &Token{ 65 Token: tok, 66 Expiry: expiry, 67 Created: time.Now(), 68 }, nil 69 } 70 71 // Inspect a JWT. 72 func (j *JWT) Inspect(t string) (*auth.Account, error) { 73 // decode the public key 74 pub, err := base64.StdEncoding.DecodeString(j.opts.PublicKey) 75 if err != nil { 76 return nil, err 77 } 78 79 // parse the public key 80 res, err := jwt.ParseWithClaims(t, &authClaims{}, func(token *jwt.Token) (interface{}, error) { 81 return jwt.ParseRSAPublicKeyFromPEM(pub) 82 }) 83 if err != nil { 84 return nil, ErrInvalidToken 85 } 86 87 // validate the token 88 if !res.Valid { 89 return nil, ErrInvalidToken 90 } 91 claims, ok := res.Claims.(*authClaims) 92 if !ok { 93 return nil, ErrInvalidToken 94 } 95 96 // return the token 97 return &auth.Account{ 98 ID: claims.Subject, 99 Issuer: claims.Issuer, 100 Type: claims.Type, 101 Scopes: claims.Scopes, 102 Metadata: claims.Metadata, 103 }, nil 104 } 105 106 // String returns JWT. 107 func (j *JWT) String() string { 108 return "jwt" 109 }