当前位置:网站首页>go学习 ------jwt的相关知识

go学习 ------jwt的相关知识

2022-07-05 14:49:00 周 -_-

一、基本介绍

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

二、下载

go get -v "github.com/dgrijalva/jwt-go"

三、使用

1、 设置相关的变量和结构

type JwtClaims struct {
     //token 里面添加用户信息,验证token后可能会用到用户信息
	jwt.StandardClaims
	UserID   int    `json:"user_id"`
	UserName string `json:"user_name"`
	Password string `json:"password"`
}

var (
	Secret     = "YuFen" //加盐:签名密匙
	ExpireTime = 20      //token有效用时 20s
)

2、创建一个方法生成token

func GetToken(claims *JwtClaims) (string, error) {
    
	token := jwt.NewWithClaims(jwt.SigningMethodES256, claims) //跟距指定的签名方法,和claims进行加密
	signedString, err := token.SignedString([]byte(Secret))    //生成的token进行密匙签名使用Secret进行加密
	if err != nil {
    
		return "", err
	}
	return signedString, nil
}

3 、在login()获取到生成token所需要的信息

func UserLogin(c *gin.Context) {
    
	var user model.User
	user.Name = c.PostForm("Name")
	user.Password = c.PostForm("Password")
	err := model.UserLogin(user)
	if err != nil {
    
		c.JSON(http.StatusBadRequest, gin.H{
    
			"msg": "登录失败",
			//"data":Users,
			//401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
		})
	} else {
    
		C, _ = model.GetUser(user.Name)
		claims := &utils.JwtClaims{
    
			UserID:   C.Id,
			UserName: C.Name,
			Password: C.Password,
		}
		claims.IssuedAt = time.Now().Unix()
		claims.ExpiresAt = time.Now().Add(time.Second * time.Duration(utils.ExpireTime)).Unix()
		s, err := utils.GetToken(claims)
		if err != nil {
    
			c.String(http.StatusNotFound, err.Error())
			return
		}
		c.JSON(http.StatusOK, gin.H{
    
			"msg": "登录成功",
			"jwt": s,
		})
	}
}

4、对生成的token进行解密


func verifyAction(strToken string) (*JWTClaims, error) {
    
	token, err := jwt.ParseWithClaims(strToken, &JWTClaims{
    }, func(token *jwt.Token) (interface{
    }, error) {
    
		return []byte(Secret), nil //该函数是实现将前端携带的Token进行相关的解密,获得加密前的token数据
	})
	if err != nil {
    
		return nil, errors.New(ErrorReason_ReLogin)
	}
	claims, ok := token.Claims.(*JWTClaims) // 根据解密的token获取claims声明信息
	if !ok {
    
		return nil, errors.New(ErrorReason_ReLogin)
	}
	if err := token.Claims.Valid(); err != nil {
    
		return nil, errors.New(ErrorReason_ReLogin)
	}
	return claims, nil

verifyAction()里面还有一个核心那就是 token.Claims.Valid() (该函数是验证token是否失效)

失效的原理:很简单,那就是在login登录的时候获取的token时候我们已经设定了失效的时长,上面是10秒。然后当执行该函数的时候,会自动和的判断当前的时间和过期时间是否超期,未超期,则表示正常使用,否则会报错返回,最后执行错误响应 errors.New(ErrorReason_ReLogin)

5、更新token


func refresh(c *gin.Context) {
    
	strToken := c.Query("token")
	claims, err := verifyAction(strToken)
 
	if err != nil {
    
		c.String(http.StatusNotFound, err.Error())
		return
	}
	claims.ExpiresAt = time.Now().Unix() + (claims.ExpiresAt - claims.IssuedAt) // 失效的时间
	signedToken, err := getToken(claims)
	if err != nil {
    
		c.String(http.StatusNotFound, err.Error())
		return
	}
	c.String(http.StatusOK, signedToken)
}

原网站

版权声明
本文为[周 -_-]所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_63593747/article/details/125585249

随机推荐