package jwt import ( "context" "fmt" "pro2d/src/common" "pro2d/src/components/logger" "time" jwt "github.com/dgrijalva/jwt-go" "google.golang.org/grpc/metadata" ) func CreateToken(uid string) (tokenString string) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "iss": "pro2d-app-server", "aud": "pro2d-app-server", "nbf": time.Now().Unix(), "exp": time.Now().Add(time.Hour).Unix(), "sub": "pro2d", "uid": uid, }) tokenString, err := token.SignedString([]byte(common.Pro2DTokenSignedString)) if err != nil { panic(err) } return tokenString } func ParseToken(tokenStr string) string { var clientClaims Claims token, err := jwt.ParseWithClaims(tokenStr, &clientClaims, func(token *jwt.Token) (interface{}, error) { if token.Header["alg"] != "HS256" { //panic("ErrInvalidAlgorithm") logger.Error("ErrInvalidAlgorithm") return nil, nil } return []byte(common.Pro2DTokenSignedString), nil }) if err != nil { logger.Error("jwt parse error") return "" } if !token.Valid { logger.Error("ErrInvalidToken") return "" } return clientClaims.Uid } // Claims defines the struct containing the token claims. type Claims struct { jwt.StandardClaims Uid string } // 从 context 的 metadata 中,取出 token func getTokenFromContext(ctx context.Context) (string, error) { md, ok := metadata.FromIncomingContext(ctx) if !ok { return "", fmt.Errorf("ErrNoMetadataInContext") } // md 的类型是 type MD map[string][]string token, ok := md["authorization"] if !ok || len(token) == 0 { return "", fmt.Errorf("ErrNoAuthorizationInMetadata") } // 因此,token 是一个字符串数组,我们只用了 token[0] return token[0], nil } func CheckAuth(ctx context.Context) string { tokenStr, err := getTokenFromContext(ctx) if err != nil { logger.Error("get token from context error") return "" } return ParseToken(tokenStr) } // AuthToken 自定义认证 客户端使用 type AuthToken struct { Token string } func (c AuthToken) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { return map[string]string{ "authorization": c.Token, }, nil } func (c AuthToken) RequireTransportSecurity() bool { return false }