jwt-go(Json web token)之Hash方法

核心代码如下:

package main

import (
	"github.com/dgrijalva/jwt-go" //快速生成token
	"temp/Gin/gin-go/model"
	"time"
)

var jwtKey = []byte("a_secret_key") //证书签名秘钥(该秘钥非常重要,如果client端有该秘钥,就可以签发证书了)

type Claims struct {
	UserId uint
	jwt.StandardClaims
}
//分发证书
func ReleaseToken(user model.User) (string, error)  {
	expirationTime := time.Now().Add(7 * 24 * time.Hour) //截止时间:从当前时刻算起,7天
	claims := &Claims{
		UserId:         user.ID,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expirationTime.Unix(), //过期时间
			IssuedAt: time.Now().Unix(), //发布时间
			Issuer: "jiangzhou", //发布者
			Subject: "user token", //主题
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) //生成token
	tokenString, err := token.SignedString(jwtKey) //签名

	if err != nil {
		return "", err
	}

	return tokenString, nil
}
//解析证书
func ParseToken(tokenString string) (*jwt.Token, *Claims, error){
	claims := &Claims{}
	token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (i interface{}, err error) {
		return jwtKey, nil
	})
	return token, claims, err
}

token验证:

//token认证中间件(权限控制)
func AuthMiddleware() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		auth:="jiangzhou"
		// 获取authorization header
		tokenString := ctx.GetHeader("Authorization") //postman测试:在Headers中添加: key:Authorization;value:jiangzhou:xxx(token值)
		//fmt.Println(tokenString)
		//fmt.Println(strings.HasPrefix(tokenString,auth+""))
		// 无效的token
		//if tokenString == "" || !strings.HasPrefix(tokenString, "Bearer ") { //验证token的前缀为:
		if tokenString == "" || !strings.HasPrefix(tokenString, auth+":") { //验证token的前缀为:
			ctx.JSON(http.StatusUnauthorized, gin.H{"code": 401, "msg": "权限不足"})
			ctx.Abort()
			return
		}
		index:=strings.Index(tokenString,auth+":") //找到token前缀对应的位置
		tokenString = tokenString[index+len(auth)+1:] //截取真实的token(开始位置为:索引开始的位置+关键字符的长度+1(:的长度为1))
		//fmt.Println("截取之后的数据:",tokenString)
		token, claims, err := common.ParseToken(tokenString)
		if err != nil || !token.Valid { //解析错误或者过期等
			ctx.JSON(http.StatusUnauthorized, gin.H{"code": 401, "msg": "权限不足"})
			ctx.Abort()
			return
		}

		// 验证通过后获取claim 中的userId
		userId := claims.UserId
		DB := common.GetDB()
		var user model.User
		DB.First(&user, userId)

		// 用户
		if user.ID == 0 {
			ctx.JSON(http.StatusUnauthorized, gin.H{"code": 401, "msg": "权限不足"})
			ctx.Abort()
			return
		}

		// 用户存在 将user 的信息写入上下文
		ctx.Set("user", user) //将key-value值存储到context中
		// before request
		ctx.Next()//执行内部的pending handlers
	}
}

采用的web框架为Gin,通过中间件来实现验证。在以上代码中,签名采用的是Hash256。

猜你喜欢

转载自blog.csdn.net/weixin_42117918/article/details/107020653