jwt-go鉴权及应用| 青训营笔记

147 阅读2分钟

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

JWT是什么

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

JWT-go在本青训营项目中的应用

生成Token

使用 jwt-go 库生成 token,我们需要定义需求(claims),也就是说我们需要通过 jwt 传输的数据。假如我们需要传输Username,我们可以定义 Claims 结构体,其中包含Username 字段,还有在 jwt-go 包预定义的 jwt.StandardClaims。 使用 jwt-go 库根据指定的算法生成 jwt token ,主要用到两个方法:

jwt.NewWithClaims 方法 利用claim结构体创建token实例

func jwt.NewWithClaims(method jwt.SigningMethod, claims jwt.Claims) *jwt.Token

SignedString 方法根据传入的空接口类型参数 key,返回完整的签名令牌。

func (*jwt.Token).SignedString(key interface{}) (string, error)
package jwt

import (
	"errors"
	"fmt"
	"time"

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

//token的过期时长
const TokenExpireDuration = time.Hour * 2
//secret,签名时使用
var MySecret = []byte("xxxxxx")

//用来生成token的struct
type MyClaims struct {
	Username string `json:"username"`
	jwt.StandardClaims
}
//创建token
func GenToken(username string) (string, error) {
	c := MyClaims{
		username, // 自定义字段
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
			Issuer:    "my-project",                               // 签发人
		},
	}
	// 使用指定的签名方法创建签名对象
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	// 使用指定的secret签名并获得完整的编码后的字符串token
	return token.SignedString(MySecret)
}

解析Token

使用 jwt-go 库解析 token,主要用到两个方法,分别用通过与解析传入的 token 字符串,和根据 MyClaims 结构体定义的相关属性要求进行校验。

jwt.ParseWithClaims 方法:

func jwt.ParseWithClaims(tokenString string, claims jwt.Claims, keyFunc jwt.Keyfunc) (*jwt.Token, error)

jwt.ParseWithClaims 方法用于解析鉴权的声明,返回 *jwt.TokenValid 方法用于校验鉴权的声明。

// 解析token
func ParseToken(tokenString string) (*MyClaims, error) {

	token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (i interface{}, err error) {
		return MySecret, nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*MyClaims); ok && token.Valid { // 校验token
		fmt.Println("jwt ok")
		fmt.Println(claims.Username)
		return claims, nil
	}
	return nil, errors.New("invalid token")
}

越权的处理

  • 水平越权风险: 只有一类用户,不存在多用户之间的水平越权问题。

  • 垂直越权风险: 用户由登录态和未登录态两种调用状态,通过token验证防止越权