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