NewWithClaims
函数claims := jwt.MapClaims{}
claims["sub"] = "1234567890"
claims["name"] = "John Doe"
claims["iat"] = time.Now().Unix()
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
在这个例子中,首先创建了一个MapClaims
类型的claims
对象,它本质上是一个map[string]interface{}
。然后向其中添加了用户 ID(sub
)、姓名(name
)和签发时间(iat
)等信息。接着使用NewWithClaims函数创建了一个新的 JWT,指定签名方法为HS256
,将claims
作为声明部分传入。
SignedString
函数NewWithClaims
创建 JWT 结构体后,SignedString
函数用于对 JWT 进行签名并生成最终的 JWT 字符串。它接受一个字节切片作为参数,这个字节切片代表用于签名的密钥。密钥的安全性至关重要,因为它用于确保 JWT 的完整性和真实性。signedToken, err := token.SignedString([]byte("my_secret_key"))
if err!= nil {
fmt.Println("签名出错:", err)
return
}
fmt.Println("生成的JWT:", signedToken)
这里将之前创建的token
(通过NewWithClaims
函数得到)使用SignedString
函数进行签名。传入字节切片形式的密钥[]byte("my_secret_key")
,如果签名过程没有错误,就会得到最终的 JWT 字符串signedToken
,可以将这个字符串发送给客户端用于后续的身份验证等操作。
Parse
函数tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte("my_secret_key"), nil
})
if err!= nil {
fmt.Println("解析出错:", err)
return
}
在这个示例中,给定一个 JWT 字符串tokenString
,使用Parse
函数进行解析。在第二个参数的函数中,返回了字节切片形式的密钥[]byte("my_secret_key")
用于签名验证。如果解析过程中出现错误,例如 JWT 格式错误或者签名验证失败,err
就不会为nil
,可以根据err
进行相应的错误处理。
ParseWithClaims
函数Parse
函数类似,但它更侧重于将解析后的声明(Claims)直接转换为指定的类型。这在需要直接访问和使用 JWT 载荷中的声明信息时非常有用。它接受三个主要参数,第一个是 JWT 字符串,第二个是用于存储声明的变量(需要实现Claims
接口),第三个是一个函数用于返回验证签名所需的密钥。claims := jwt.MapClaims{}
_, err := jwt.ParseWithClaims(tokenString, &claims, func(token *jwt.Token) (interface{}, error) {
return []byte("my_secret_key"), nil
})
if err!= nil {
fmt.Println("解析出错:", err)
return
}
fmt.Println("用户ID:", claims["sub"])
这里首先创建了一个MapClaims
类型的claims
变量,然后使用ParseWithClaims
函数将tokenString
解析后的声明存储到claims
变量中。如果解析成功且签名验证通过,就可以像访问普通的map
一样从claims
中获取载荷中的信息,如示例中的用户 ID(sub
)。
Validate
函数Parse
和ParseWithClaims
函数在解析过程中会验证签名,但在实际应用中,可能还需要对 JWT 中的声明进行更多自定义的验证,例如检查过期时间、权限范围等。这就需要自定义一个验证函数,在这个函数中可以综合使用Parse
或ParseWithClaims
以及其他逻辑来进行全面的 JWT 验证。func validateToken(token *jwt.Token, claims jwt.Claims, secretKey []byte) bool {
// 验证签名
_, err := jwt.ParseWithClaims(token.Raw, claims, func(t *jwt.Token) (interface{}, error) {
return secretKey, nil
})
if err!= nil {
return false
}
// 可以添加更多自定义的声明验证逻辑,比如检查过期时间
if exp, ok := claims.(jwt.MapClaims)["exp"].(float64); ok {
if int64(exp) < time.Now().Unix() {
return false
}
}
return true
}
在这个自定义的validateToken
函数中,首先通过ParseWithClaims
验证 JWT 的签名。然后,通过类型断言检查声明中的过期时间(exp
)是否存在并且是否已经过期(将其转换为int64
后与当前时间的Unix
时间戳进行比较)。可以根据实际需求在这个函数中添加更多的验证逻辑,比如检查权限相关的声明等,以确保 JWT 的完整性和合法性满足应用程序的要求。