怎么在在 go 中使用 jwt

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,企业版 4核16GB
推荐场景:
HTAP混合负载
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: JWT(JSON Web Tokens)由三个部分组成:Header、Payload和Signature。Header通常包含`alg`(算法)和`typ`(类型)字段,如`HS256`或`JWT`。Payload则包括官方标准字段如`iss`(签发人)、`exp`(过期时间)等,以及可自定义的数据,比如用户信息。Signature用于验证JWT未被篡改,通过HMAC算法(如HS256)或非对称加密(如RS256)确保安全性。完整JWT是这三部分经过编码和签名后的结果。

jwt 由三部分组成:

  1. header 头部
  • 官方规定的字段:
  • alg: (algorithm) 算法
  • typ: (type) 类型
  • cty: (content type) 内容类型
  • kid: (key ID) 密钥 ID
  • x5u: (X.509 URL) X.509 地址
  • x5c: (X.509 certificate chain) X.509 证书链
  • crit: (critical) 关键
  • 一般使用 algtype,例如

json

  • 复制代码
{
  "alg": "HS256",
  "typ": "JWT"
}
  1. payload 负载
  • 官方规定的字段
  • iss: (issuer) 签发人
  • exp: (expiration time) 过期时间
  • sub: (subject) 主题
  • aud: (audience) 受众
  • nbf: (Not Before) 生效时间
  • iat: (Issued At) 签发时间
  • jti: (JWT ID) 编号
  • 自定义字段
  • user: 用户信息
  • 例如

go

  • 复制代码
{
  "exp": 1718254332,
  "iat": 1718167932,
  "user": {
    "email": "jack@gmial.com",
    "username": "jack22ssss22"
  }
}
  1. signature 签名,这个签名不能泄漏,否则会被篡改

完整的 jwt 就是把这三部分组合起来 HMACSHA256(base64UrlEncode(Header).base64UrlEncode(Payload).Signature)

HS256 加密

HS256 是一种对称加密算法,使用秘密密钥对每条消息进行签名和验证

生成 token

go

复制代码

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

go

复制代码

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

bash

复制代码

apt install openssl

生成 rsa 私钥

在当前目录下生成一个 2048 位的私钥文件 private.pem

bash

复制代码

openssl genrsa -out private.pem 2048

生成 rsa 公钥

bash

复制代码

openssl rsa -in private.pem -outform PEM -pubout -out public.pem

获取到 rsa 秘钥

go

复制代码

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

go

复制代码

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

go

复制代码

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
}

转载来源:https://juejin.cn/post/7379416139976163391

相关文章
|
1月前
|
JSON 算法 Go
go语言后端开发学习(一)——JWT的介绍以及基于JWT实现登录验证
go语言后端开发学习(一)——JWT的介绍以及基于JWT实现登录验证
|
7月前
|
SQL API Go
go-zero jwt 鉴权快速实战
go-zero jwt 鉴权快速实战
127 0
|
存储 JSON 缓存
JWT身份认证(附带源码讲解) | GO主题月
一天,正是午休时段 兵长路过胖sir座位,大吃一惊,今天胖sir居然没有打呼噜,而是在低着头聚精会神盯着一本书 兵长凑近一看,胖sir居然在看史书...
120 0
|
存储 JSON 前端开发
彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-JWT和中间件(Middleware)的使用EP07
前文再续,上一回我们完成了用户的登录逻辑,将之前用户管理模块中添加的用户账号进行账号和密码的校验,过程中使用图形验证码强制进行人机交互,防止账号的密码被暴力破解。本回我们需要为登录成功的用户生成Token,并且通过Iris的中间件(Middleware)进行鉴权操作。
彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-JWT和中间件(Middleware)的使用EP07
|
存储 JSON 安全
(12)go-micro微服务JWT跨域认证
(12)go-micro微服务JWT跨域认证
117 0
|
存储 JSON 算法
go使用JWT进行跨域认证最全教学
go使用JWT进行跨域认证最全教学
130 0
|
关系型数据库 MySQL 中间件
使用 Go HTTP 框架 Hertz 进行 JWT 认证
上一篇文章简单介绍了一个高性能的 Go HTTP 框架——Hertz,本篇文章将围绕 Hertz 开源仓库的一个 demo,讲述如何使用 Hertz 完成 JWT 的认证与授权流程。
323 0
使用 Go HTTP 框架 Hertz 进行 JWT 认证
Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务(三):RSA(RS512) 签名 JWT
Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务(三):RSA(RS512) 签名 JWT
807 0
Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务(三):RSA(RS512) 签名 JWT
|
JavaScript 中间件 API
使用JWT做RESTful API的身份验证-Go语言实现
在 使用Golang和MongoDB构建 RESTful API已经实现了一个简单的 RESTful API应用,但是对于有些API接口需要授权之后才能访问,在这篇文章中就用 jwt 做一个基于Token的身份验证,关于 jwt 请访问 JWT有详细的说明,而且有各个语言实现的库,请根据需要使用对应的版本。
3298 0
|
2月前
|
安全 数据安全/隐私保护
Springboot+Spring security +jwt认证+动态授权
Springboot+Spring security +jwt认证+动态授权
147 0