golang-jwt
是go语言中用来生成和解析jwt的一个第三方库。本文中使用目前最新的v5版本。
安装
go get -u github.com/golang-jwt/jwt/v5
在代码中引用
import "github.com/golang-jwt/jwt/v5"
结构体
假设jwt原始的payload如下,username,exp为过期时间,nbf为生效时间,iat为签发时间。第一个是业务非敏感参数,后三者为jwt标准的参数。
{
"username": "zhangsan",
"exp": 1681869394,
"nbf": 1681782994,
"iat": 1681782994
}
对此编写结构体,其中jwt.RegisteredClaims
包含了exp
、nbf
和iat
三个字段。
type User struct {
Username string `json:"username"`
jwt.RegisteredClaims // v5版本新加的方法
}
生成jwt
入参为username和密钥,返回jwt的字符串和error。
func GenerateJWT(username, secretKey string) (string, error){
claims := User{
username,
jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)), // 过期时间24小时
IssuedAt: jwt.NewNumericDate(time.Now()), // 签发时间
NotBefore: jwt.NewNumericDate(time.Now()), // 生效时间
},
}
// 使用HS256签名算法
t := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
s, err := t.SignedString([]byte(secretKey))
return s, err
}
解析jwt
func ParseJwt(tokenstring, secretKey string) (*User, error) {
t,err := jwt.ParseWithClaims(tokenstring, &User{}, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
if claims,ok := t.Claims.(*User); ok && t.Valid {
return claims, nil
} else {
return nil,err
}
}
完整示例
package main
import (
"fmt"
"os"
"time"
"github.com/golang-jwt/jwt/v5"
)
type User struct {
Username string `json:"username"`
jwt.RegisteredClaims // v5版本新加的方法
}
// 生成JWT
func GenerateJWT(username, secretKey string) (string, error) {
claims := User{
username,
jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)), // 过期时间24小时
IssuedAt: jwt.NewNumericDate(time.Now()), // 签发时间
NotBefore: jwt.NewNumericDate(time.Now()), // 生效时间
},
}
// 使用HS256签名算法
t := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
s, err := t.SignedString([]byte(secretKey))
return s, err
}
// 解析JWT
func ParseJwt(tokenstring, secretKey string) (*User, error) {
t,err := jwt.ParseWithClaims(tokenstring, &User{}, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
if claims,ok := t.Claims.(*User); ok && t.Valid {
return claims, nil
} else {
return nil,err
}
}
func main() {
var secretKey string = "qwertyuiop"
s, err := GenerateJWT("zhangsan", secretKey)
if err != nil {
fmt.Println("generate jwt failed, ", err)
os.Exit(1)
}
fmt.Printf("%s\n", s)
// 解析jwt
claims, err := ParseJwt(s, secretKey)
if err != nil {
fmt.Println("parse jwt failed, ", err)
os.Exit(1)
}
fmt.Printf("%+v\n", claims)
}
参考