jwt-go库生成与解析token | 青训营

599 阅读2分钟

token介绍

JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种方式,用于在各方之间安全地将信息作为 JSON 对象传输。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对对 JWT 进行签名。

尽管可以对 JWT 进行加密以提供双方之间的保密性,但我们将重点关注已签名的令牌(signed tokens)。签名的令牌可以验证其中包含的声明的完整性,而加密的令牌则将这些声明隐藏。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是对其进行签名的一方。

Token是一种服务端生成的一串字符串,以作客户端进行请求的一个令牌。当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。 在用户鉴权中,Token可以用来验证用户是否拥有访问系统的权利。对用户进行鉴权,防止非法用户占用网络资源,非法用户接入网络,被骗取关键信息。——来自星火大模型

jwt-go 安装

go get -u github.com/dgrijalva/jwt-go@v3.2.0

生成token

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

type Claims struct { 
    ID int64 
    Username string 
    jwt.StandardClaims 
    }

使用jwt-go生成token主要用到jwt-go库中的 jwt.NewWithClaims 和 SignedString 这两种方法

jwt.NewWithClaims

func jwt.NewWithClaims(method jwt.SigningMethod, claims jwt.Claims) *jwt.Token jwt.NewWithClaims 可以根据实例化的Claims结构体来创建token,其中jwt.SigningMethod类型的method包含三种不同的加密算法,分别为:jwt.SigningMethodHS256jwt.SigningMethodHS384jwt.SigningMethodHS512 jwt.Claims类型的claims为自定义的claims

SignedString

func (*jwt.Token).SignedString(key interface{}) (string, error) SignedString 方法根据传入的空接口类型参数 key,返回完整的签名令牌。

示例

func GenerateToken() (string, error) { 
    nowTime := time.Now() 
    expireTime := nowTime.Add(300 * time.Second) 
    issuer := "frank" 
    claims := MyCustomClaims{ 
        ID: 10001, 
        Username: "frank", 
        StandardClaims: jwt.StandardClaims{ 
            ExpiresAt: expireTime.Unix(), 
            Issuer: issuer, 
        }, 
    } 
    token := jwt.NewWithClaims(jwt.SigningMethodHS256,claims)
    return token.SignedString([]byte("golang"))   // "golang" 为此例的key,可以换成其他
}

解析token

使用 jwt-go 库解析 token,主要用到 jwt.ParseWithClaims 方法和 Valid 方法

jwt.ParseWithClaims

func jwt.ParseWithClaims(tokenString string, claims jwt.Claims, keyFunc jwt.Keyfunc) (*jwt.Token, error) jwt.ParseWithClaims 方法用于解析鉴权的声明,返回 *jwt.Token。

Valid

Valid 方法用于校验鉴权的声明。

示例

func ParseToken(token string) (*MyCustomClaims, error) { 
    tokenClaims, err := jwt.ParseWithClaims(token, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) { 
        return []byte("golang"), nil 
    }) 
    if err != nil { 
        return nil, err 
    } 
    if tokenClaims != nil { 
        if claims, ok := tokenClaims.Claims.(*MyCustomClaims); ok && tokenClaims.Valid { 
            return claims, nil 
        }
    }
    return nil, err 
}