JWT的简单介绍和使用 | 青训营笔记

137 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记

1. 什么是JWT

JWT(JSON Web Token),简单理解可以看作是一个字符串,由三个部分组成,分别是HEADERPAYLOADSIGNATURE,用·将三个部分分隔。

image.png

  • HEADER

HEADER一般有两个字段,一个是alg(signing algorithm),一般为HMAC SHA256或者RSA,另一个是typ(type of the token),内容是JWT,这个部分经过Base64编码得到JWT的第一个部分。

  • PAYLOAD

PAYLOAD包含claimsclaims是一个实体的声明和附加信息。可以包含如用户信息和过期时间等,这个部分经过Base64编码得到JWT的第二个部分。

  • SIGNATURE

SIGNATURE使用一个签名算法,将用·隔开的经过Base64编码的前两个部分和一个密码字符串,一起生成。密码字符串存放在服务器上,不对外公开,检查这个部分,可以发现JWT是否被篡改。例如下面的例子是用HMAC SHA256算法签名。

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

这个部分经过Base64编码得到JWT的第三个部分。

我们利用JWT可以对登录用户的行为进行鉴权,这是一个开销较小的方式。

2. golang-jwt

golang-jwt是一个被广泛使用的jwt包,接下来介绍他的基本使用方式

  • 定义claims和密码字符串
type MyClaims struct {
	Username string `json:"username"`
	jwt.StandardClaims
}

var secretKey = []byte("secret_key")
  • 生成token
func GenerateToken(username string) (string, error) {
	var claims MyClaims
	claims.Username = username
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	return token.SignedString(secretKey)
}
  • 解析token
func ParserToken(tokenString string) (*MyClaims, error) {
	token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
		return secretKey, nil
	})
	if err != nil {
		return nil, errno.ErrTokenInvalid
	}

	if token != nil {
		if claims, ok := token.Claims.(*MyClaims); ok && token.Valid {
			return claims, nil
		}
		return nil, errno.ErrTokenInvalid
	}

	return nil, errno.ErrTokenInvalid
}

3. gin-jwt

gin-jwt是一个gin的jwt扩展,他是在golang-jwt的基础上开发的。

他提供了一个LoginHandler,一个LogoutHandler,分别来处理Login request flow和Logout Request flow。还可以使用MiddlewareFunc对一些需要jwt token的子过程提供一个中间件方法的接口。