Golang学习笔记-jwt
简介
参考地址:https://jwt.io/
JWT全称json web token,是目前主流的跨域认证解决方案之一
JWT的原理:在服务器认证以后生成3个Json对象,将这3个对象分别通过base64编码,将编码后的结果根据页眉中声明的加密方式进行签名,最终以.
作为分隔符组合成一个字符串返回给用户。它分为三部分:页眉
、有效载荷
、签名
,这三部分中间由3个.
分割,最终的数据格式是 页眉.有效负荷.签名
。
页眉:由令牌类型
和 令牌的签名算法
组成
有效载荷:由已注册
、公共
和 私有声明
组成,
签名:签名部分根据页眉中的签名算法、密钥以及有效载荷生成
栗子
package main
import (
"errors"
"fmt"
"github.com/golang-jwt/jwt/v5"
"math/rand"
"time"
)
type MyCustomClaims struct {
UserID int
Username string
GrantScope string
jwt.RegisteredClaims
}
// 签名密钥
const sign_key = "hello jwt"
// 随机字符串
var letters = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func randStr(str_len int) string {
rand_bytes := make([]rune, str_len)
for i := range rand_bytes {
rand_bytes[i] = letters[rand.Intn(len(letters))]
}
return string(rand_bytes)
}
func generateTokenUsingHs256() (string, error) {
claim := MyCustomClaims{
UserID: 000001,
Username: "Tom",
GrantScope: "read_user_info",
RegisteredClaims: jwt.RegisteredClaims{
Issuer: "jruing", // 签发者
Subject: "zhangsan", // 签发对象
Audience: jwt.ClaimStrings{"Android_APP", "IOS_APP"}, //签发受众
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour)), //过期时间
NotBefore: jwt.NewNumericDate(time.Now().Add(time.Second)), //最早使用时间
IssuedAt: jwt.NewNumericDate(time.Now()), //签发时间
ID: randStr(10), // wt ID, 类似于盐值
},
}
token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claim).SignedString([]byte(sign_key))
return token, err
}
func parseTokenHs256(token_string string) (*MyCustomClaims, error) {
token, err := jwt.ParseWithClaims(token_string, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(sign_key), nil //返回签名密钥
})
if err != nil {
return nil, err
}
if !token.Valid {
return nil, errors.New("claim invalid")
}
claims, ok := token.Claims.(*MyCustomClaims)
if !ok {
return nil, errors.New("invalid claim type")
}
return claims, nil
}
func main() {
// 生成jwt token
token, err := generateTokenUsingHs256()
if err != nil {
panic(err)
}
fmt.Println("Token = ", token)
time.Sleep(time.Second * 2)
// 解析jw ttoken
my_claim, err := parseTokenHs256(token)
if err != nil {
panic(err)
}
fmt.Println("my claim = ", my_claim)
}