12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- package auth
- import (
- "context"
- "time"
- "git.i2edu.net/i2/go-zero/core/collection"
- "git.i2edu.net/i2/go-zero/core/stores/redis"
- "google.golang.org/grpc/codes"
- "google.golang.org/grpc/metadata"
- "google.golang.org/grpc/status"
- )
- const defaultExpiration = 5 * time.Minute
- // An Authenticator is used to authenticate the rpc requests.
- type Authenticator struct {
- store *redis.Redis
- key string
- cache *collection.Cache
- strict bool
- }
- // NewAuthenticator returns an Authenticator.
- func NewAuthenticator(store *redis.Redis, key string, strict bool) (*Authenticator, error) {
- cache, err := collection.NewCache(defaultExpiration)
- if err != nil {
- return nil, err
- }
- return &Authenticator{
- store: store,
- key: key,
- cache: cache,
- strict: strict,
- }, nil
- }
- // Authenticate authenticates the given ctx.
- func (a *Authenticator) Authenticate(ctx context.Context) error {
- md, ok := metadata.FromIncomingContext(ctx)
- if !ok {
- return status.Error(codes.Unauthenticated, missingMetadata)
- }
- apps, tokens := md[appKey], md[tokenKey]
- if len(apps) == 0 || len(tokens) == 0 {
- return status.Error(codes.Unauthenticated, missingMetadata)
- }
- app, token := apps[0], tokens[0]
- if len(app) == 0 || len(token) == 0 {
- return status.Error(codes.Unauthenticated, missingMetadata)
- }
- return a.validate(app, token)
- }
- func (a *Authenticator) validate(app, token string) error {
- expect, err := a.cache.Take(app, func() (interface{}, error) {
- return a.store.Hget(a.key, app)
- })
- if err != nil {
- if a.strict {
- return status.Error(codes.Internal, err.Error())
- }
- return nil
- }
- if token != expect {
- return status.Error(codes.Unauthenticated, accessDenied)
- }
- return nil
- }
|