package server import ( "encoding/json" "errors" "golang.org/x/net/context" "google.golang.org/grpc/metadata" "gopkg.in/redis.v2" "xiaoniaokuaiyan.com/xiaoniao/util" ) type AuthService interface { GetAccessToken(strToken string) (interface{}, error) } func AuthGrpc(ctx context.Context) error { md, _ := metadata.FromIncomingContext(ctx) var clientid []string var hasOk bool if clientid, hasOk = md["clientid"]; !hasOk { return errors.New("clientid required") } if tokenKey, ok := md["token"]; !ok { return errors.New("token is empty") } else { return ValidateToken(tokenKey[0], clientid[0]) } } func ValidateToken(tokenStr string, clientid string) error { token, err := GetTokenFromRedis(clientid) if err != nil { return err } if token.expired() { go func() { var client *redis.Client = util.GetRedis() client.Select(REDIS_API_AUTH_DB) client.HDel(REDIS_API_AUTH_KEY, clientid) }() return TokenExipiredError } if token.AccessToken != tokenStr { return errors.New("wrong token") } if !token.IsValid() { return errors.New("invalid token") } return nil } var TokenKeyNotFoundError error = errors.New("token key not found") var TokenExipiredError error = errors.New("token expired") func GetTokenFromRedis(tokenKey string) (*AuthToken, error) { if tokenKey == "" { return nil, errors.New("token key is empty") } var client *redis.Client = util.GetRedis() statusCmd := client.Select(REDIS_API_AUTH_DB) if err := statusCmd.Err(); err != nil { return nil, err } strCmd := client.HGet(REDIS_API_AUTH_KEY, tokenKey) if tokenStr, err := strCmd.Result(); err != nil { return nil, TokenKeyNotFoundError } else { token := &AuthToken{} err = json.Unmarshal([]byte(tokenStr), token) return token, nil } }