JWT的使用

jwt的介绍请看官网:JSON Web Tokens - jwt.ioJSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS).https://jwt.io/

第一种:

一、下载jwt

go get github.com/golang-jwt/jwt/v4

二、引入jwt

import (
	"github.com/golang-jwt/jwt/v4"
)

三 、使用

var currentUserKey struct{}

type CurrentUser struct {
	UserID uint
}

第一种:
//func GenerateToken(secret string, userid uint) string {
//	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
//		"userid": userid,
//		"nbf":    time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
//	})
//	// Sign and get the complete encoded token as a string using the secret
//	tokenString, err := token.SignedString([]byte(secret))
//	if err != nil {
//		panic(err)
//	}
//	return tokenString
//}
//
//func JWTAuth(secret string) middleware.Middleware {
//	return func(handler middleware.Handler) middleware.Handler {
//		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
//			if tr, ok := transport.FromServerContext(ctx); ok {
//				tokenString := tr.RequestHeader().Get("Authorization")
//				auths := strings.SplitN(tokenString, " ", 2)
//				if len(auths) != 2 || !strings.EqualFold(auths[0], "Token") {
//					return nil, errors.New("jwt token missing")
//				}
//
//				token, err := jwt.Parse(auths[1], func(token *jwt.Token) (interface{}, error) {
//					// Don't forget to validate the alg is what you expect:
//					if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
//						return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
//					}
//
//					// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
//					return []byte(secret), nil
//				})
//				if err != nil {
//					return nil, err
//				}
//				if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
//					// put CurrentUser into ctx
//					if u, ok := claims["userid"]; ok {
//						ctx = WithContext(ctx, &CurrentUser{UserID: uint(u.(float64))}) //u-->interface{} is float64
//					}
//				} else {
//					return nil, errors.New("Token Invalid")
//				}
//			}
//			return handler(ctx, req)
//		}
//	}
//}

//第二种:
type MyCustomClaims struct {
	UserID uint `json:"user_id"`
	jwt.RegisteredClaims
}

func GenerateToken(mySigningKey string, userid uint) string {
	// Create the claims
	claims := MyCustomClaims{
		userid,
		jwt.RegisteredClaims{
			// A usual scenario is to set the expiration time relative to the current time
			// 通常的情况是相对于当前时间设置过期时间
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
			IssuedAt:  jwt.NewNumericDate(time.Now()),
			NotBefore: jwt.NewNumericDate(time.Now()),
			//Issuer:    "test",
			//Subject:   "somebody",
			//ID:        "1",
			//Audience:  []string{"somebody_else"},
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString([]byte(mySigningKey))
	if err != nil {
		panic(err)
	}
	return tokenString
}

func JWTAuth(mySigningKey string) middleware.Middleware {
	return func(handler middleware.Handler) middleware.Handler {
		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
			if tr, ok := transport.FromServerContext(ctx); ok {
				tokenString := tr.RequestHeader().Get("Authorization")
				//auths := strings.SplitN(tokenString, " ", 2)
				//if len(auths) != 2 || !strings.EqualFold(auths[0], "Token") {
				//	return nil, errors.New("jwt token missing")
				//}

				token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
					// Don't forget to validate the alg is what you expect:
					if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
						return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
					}

					// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
					return []byte(mySigningKey), nil
				})
				if err != nil {
					return nil, err
				}
				if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
					if claims.UserID != 0 {
						ctx = WithContext(ctx, &CurrentUser{UserID: claims.UserID})
					}
				} else {
					return nil, errors.New("Token Invalid")
				}
			}
			return handler(ctx, req)
		}
	}
}

func FromContext(ctx context.Context) *CurrentUser {
	return ctx.Value(currentUserKey).(*CurrentUser)
}

func WithContext(ctx context.Context, user *CurrentUser) context.Context {
	return context.WithValue(ctx, currentUserKey, user)
}

第二种:

一、下载jwt

go get github.com/dgrijalva/jwt-go

二、引入jwt

import (
	"github.com/dgrijalva/jwt-go"
)

三 、使用

1、jwt对token的生成与验证

package jwt

import (
	"fmt"
	"reflect"
	"time"

	"github.com/dgrijalva/jwt-go"
)

var JwtSecret = "sfgafasgljasg24576asg555asg35435"

type Claims struct {
	Id           string `json:"id"`
	AccountName  string `json:"account_name"`  //账户名
	jwt.StandardClaims
}

//生成token
func GenerateToken(id, accountName, hospitalCode string) (string, error) {
	nowTime := time.Now()
	expireTime := nowTime.Add(24 * time.Hour) //time.Hour * time.Duration(24)
	claims := Claims{
		id,
		accountName,
		jwt.StandardClaims{
			IssuedAt:  nowTime.Unix(),
			ExpiresAt: expireTime.Unix(),
			Issuer:    "ffrct",
		},
	}

	tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	token, err := tokenClaims.SignedString([]byte(JwtSecret))
	return token, err
}

//验证token
func ParseToken(token string) (*Claims, error) {
	tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(JwtSecret), nil
	})

	if tokenClaims != nil {
		if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
			return claims, nil
		}
	}
	return nil, err
}

func GetParamValueFromClaims(key string, claims jwt.Claims) string {
	v := reflect.ValueOf(claims)
	if v.Kind() == reflect.Map {
		for _, k := range v.MapKeys() {
			value := v.MapIndex(k)

			if fmt.Sprintf("%s", k.Interface()) == key {
				return fmt.Sprintf("%v", value.Interface())
			}
		}
	}
	return ""
}

func GetIdFromCookie(ctx *bm.Context, cookieName string) string {
	cookie, err := ctx.Request.Cookie(cookieName)
	if err != nil {
		return "GET COOKIE ERR"
	}
	if cookie.Value == "" {
		return "COOKIE VALUE IS NULL"
	}
	Authorization := cookie.Value
	t, _ := jwt.Parse(Authorization, func(*jwt.Token) (interface{}, error) {
		return pkg_jwt.JwtSecret, nil
	})
	id := pkg_jwt.GetParamValueFromClaims("id", t.Claims)
	return id
}

2、中间件中的jwt

func JWT(args ...string) bm.HandlerFunc {
	log.Info("bm.HandlerFunc")
	return func(c *bm.Context) {
		// 需要加 判断操作人是不是本人的操作
		b := true
		cookie, err := c.Request.Cookie(args[0])
		if err != nil {
			c.JSON(nil, err_code.VerifyTokenErr)
			c.Abort() // 验证不通过,不再调用后续的函数处理
			return
		}
		if cookie.Value == "" {
			c.JSON(nil, err_code.VerifyTokenErr)
			c.Abort() // 验证不通过,不再调用后续的函数处理
			return
		}
		Authorization := cookie.Value
		//Authorization := c.Request.Header.Get("Authorization")
		var claims *pkg_jwt.Claims
		if Authorization == "" {
			b = false
		} else {
			claims, err = pkg_jwt.ParseToken(Authorization)
			if err != nil {
				switch err.(*jwt.ValidationError).Errors {
				case jwt.ValidationErrorExpired:
					b = false
				default:
					b = false
				}
			}
		}

		if !b {
			c.JSON(nil, err_code.VerifyTokenErr)
			c.Abort() // 验证不通过,不再调用后续的函数处理
			return
		}
		c.Set("claims", claims)
		c.Next() // 验证通过,会继续访问下一个中间件
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值