生成 token 一般用 jwt,常用的两种加密方式是 hs256 和 rs256,借助 "github.com/golang-jwt/jwt/v5" 这个库来实现
jwt 由三部分组成:
header头部- 官方规定的字段:
alg: (algorithm) 算法typ: (type) 类型cty: (content type) 内容类型kid: (key id) 密钥 idx5u: (x.509 url) x.509 地址x5c: (x.509 certificate chain) x.509 证书链crit: (critical) 关键
- 一般使用
alg和type,例如
- 官方规定的字段:
{
"alg": "hs256",
"typ": "jwt"
}
payload 负载
- 官方规定的字段
iss: (issuer) 签发人exp: (expiration time) 过期时间sub: (subject) 主题aud: (audience) 受众nbf: (not before) 生效时间iat: (issued at) 签发时间jti: (jwt id) 编号
- 自定义字段
user: 用户信息
- 例如
{
"exp": 1718254332,
"iat": 1718167932,
"user": {
"email": "jack@gmial.com",
"username": "jack22ssss22"
}
}
signature签名,这个签名不能泄漏,否则会被篡改
完整的 jwt 就是把这三部分组合起来 hmacsha256(base64urlencode(header).base64urlencode(payload).signature)
hs256 加密
hs256 是一种对称加密算法,使用秘密密钥对每条消息进行签名和验证
生成 token
func generatejwths256(username, email string) (string, error) {
key := []byte("secret")
tokenduration := 24 * time.hour
now := time.now()
t := jwt.newwithclaims(jwt.signingmethodhs256, jwt.mapclaims{
"user": map[string]string{
"username": username,
"email": email,
},
"iat": now.unix(),
"exp": now.add(tokenduration).unix(),
})
return t.signedstring(key)
}
验证 token
func verifyjwths256(token string) (*jwt.mapclaims, bool, error) {
var claim jwt.mapclaims
claims, err := jwt.parsewithclaims(token, &claim, func(t *jwt.token) (interface{}, error) {
return []byte("secret"), nil
})
if err != nil {
return nil, false, err
}
if claims.valid {
return &claim, true, nil
}
return nil, false, nil
}
rs256 加密
rs256 是一种非对称加密算法,使用私钥加密明文,公钥解密密文
安装 openssl
apt install openssl
生成 rsa 私钥
在当前目录下生成一个 2048 位的私钥文件 private.pem
openssl genrsa -out private.pem 2048
获取到 rsa 秘钥
var privatekey *rsa.privatekey
var publickey *rsa.publickey
func init() {
var err error
var bytes []byte
bytes, err = os.readfile("/root/uccs/realworld/private.pem")
if err != nil {
panic(err)
}
privatekey, err = jwt.parsersaprivatekeyfrompem(bytes)
if err != nil {
panic(err)
}
bytes, err = os.readfile("/root/uccs/realworld/public.pem")
if err != nil {
panic(err)
}
publickey, err = jwt.parsersapublickeyfrompem(bytes)
if err != nil {
panic(err)
}
}
生成 token
func generatejwtrs256(username, email string) (string, error) {
tokenduration := 24 * time.hour
now := time.now()
t := jwt.newwithclaims(jwt.signingmethodrs256, jwt.mapclaims{
"user": map[string]string{
"username": username,
"email": email,
},
"iat": now.unix(),
"exp": now.add(tokenduration).unix(),
})
return t.signedstring(privatekey)
}
验证 token
func verifyjwtrs256(token string) (*jwt.mapclaims, bool, error) {
var claim jwt.mapclaims
claims, err := jwt.parsewithclaims(token, &claim, func(t *jwt.token) (interface{}, error) {
return publickey, nil
})
if err != nil {
return nil, false, err
}
if claims.valid {
return &claim, true, nil
}
return nil, false, nil
}
以上就是在go中使用jwt的教程详解的详细内容,更多关于go中使用jwt的资料请关注代码网其它相关文章!
发表评论