github.com/micro/go-micro/v2@v2.9.1/auth/jwt/jwt.go (about) 1 package jwt 2 3 import ( 4 "sync" 5 "time" 6 7 "github.com/micro/go-micro/v2/auth" 8 "github.com/micro/go-micro/v2/auth/rules" 9 "github.com/micro/go-micro/v2/auth/token" 10 jwtToken "github.com/micro/go-micro/v2/auth/token/jwt" 11 ) 12 13 // NewAuth returns a new instance of the Auth service 14 func NewAuth(opts ...auth.Option) auth.Auth { 15 j := new(jwt) 16 j.Init(opts...) 17 return j 18 } 19 20 type jwt struct { 21 options auth.Options 22 jwt token.Provider 23 rules []*auth.Rule 24 25 sync.Mutex 26 } 27 28 func (j *jwt) String() string { 29 return "jwt" 30 } 31 32 func (j *jwt) Init(opts ...auth.Option) { 33 j.Lock() 34 defer j.Unlock() 35 36 for _, o := range opts { 37 o(&j.options) 38 } 39 40 j.jwt = jwtToken.NewTokenProvider( 41 token.WithPrivateKey(j.options.PrivateKey), 42 token.WithPublicKey(j.options.PublicKey), 43 ) 44 } 45 46 func (j *jwt) Options() auth.Options { 47 j.Lock() 48 defer j.Unlock() 49 return j.options 50 } 51 52 func (j *jwt) Generate(id string, opts ...auth.GenerateOption) (*auth.Account, error) { 53 options := auth.NewGenerateOptions(opts...) 54 account := &auth.Account{ 55 ID: id, 56 Type: options.Type, 57 Scopes: options.Scopes, 58 Metadata: options.Metadata, 59 Issuer: j.Options().Namespace, 60 } 61 62 // generate a JWT secret which can be provided to the Token() method 63 // and exchanged for an access token 64 secret, err := j.jwt.Generate(account) 65 if err != nil { 66 return nil, err 67 } 68 account.Secret = secret.Token 69 70 // return the account 71 return account, nil 72 } 73 74 func (j *jwt) Grant(rule *auth.Rule) error { 75 j.Lock() 76 defer j.Unlock() 77 j.rules = append(j.rules, rule) 78 return nil 79 } 80 81 func (j *jwt) Revoke(rule *auth.Rule) error { 82 j.Lock() 83 defer j.Unlock() 84 85 rules := []*auth.Rule{} 86 for _, r := range j.rules { 87 if r.ID != rule.ID { 88 rules = append(rules, r) 89 } 90 } 91 92 j.rules = rules 93 return nil 94 } 95 96 func (j *jwt) Verify(acc *auth.Account, res *auth.Resource, opts ...auth.VerifyOption) error { 97 j.Lock() 98 defer j.Unlock() 99 100 var options auth.VerifyOptions 101 for _, o := range opts { 102 o(&options) 103 } 104 105 return rules.Verify(j.rules, acc, res) 106 } 107 108 func (j *jwt) Rules(opts ...auth.RulesOption) ([]*auth.Rule, error) { 109 j.Lock() 110 defer j.Unlock() 111 return j.rules, nil 112 } 113 114 func (j *jwt) Inspect(token string) (*auth.Account, error) { 115 return j.jwt.Inspect(token) 116 } 117 118 func (j *jwt) Token(opts ...auth.TokenOption) (*auth.Token, error) { 119 options := auth.NewTokenOptions(opts...) 120 121 secret := options.RefreshToken 122 if len(options.Secret) > 0 { 123 secret = options.Secret 124 } 125 126 account, err := j.jwt.Inspect(secret) 127 if err != nil { 128 return nil, err 129 } 130 131 access, err := j.jwt.Generate(account, token.WithExpiry(options.Expiry)) 132 if err != nil { 133 return nil, err 134 } 135 136 refresh, err := j.jwt.Generate(account, token.WithExpiry(options.Expiry+time.Hour)) 137 if err != nil { 138 return nil, err 139 } 140 141 return &auth.Token{ 142 Created: access.Created, 143 Expiry: access.Expiry, 144 AccessToken: access.Token, 145 RefreshToken: refresh.Token, 146 }, nil 147 }