Golang语言使用 jwt-go 库生成和解析 token

简介: Golang语言使用 jwt-go 库生成和解析 token

01

介绍


JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种方式,用于在各方之间安全地将信息作为 JSON 对象传输。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对对 JWT 进行签名。


尽管可以对 JWT 进行加密以提供双方之间的保密性,但我们将重点关注已签名的令牌(signed tokens)。签名的令牌可以验证其中包含的声明的完整性,而加密的令牌则将这些声明隐藏。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是对其进行签名的一方。


因为本文主要是介绍 jwt-go 库的使用方法,所以关于 jwt 的内容不再深入介绍,感兴趣的读者,如果想要了解更多关于 JWT 的内容,可以访问 jwt.io。


安装 jwt-go


go get -u github.com/dgrijalva/jwt-go@v3.2.0


02

生成 token


使用 jwt-go 库生成 token,我们需要定义需求(claims),也就是说我们需要通过 jwt 传输的数据。假如我们需要传输 ID 和 Username,我们可以定义 Claims 结构体,其中包含 ID 和 Username 字段,还有在 jwt-go 包预定义的 jwt.StandardClaims。


type Claims struct {
  ID       int64
  Username string
  jwt.StandardClaims
}


jwt.StandardClaims 包含的字段:


type StandardClaims struct {
  Audience  string `json:"aud,omitempty"`
  ExpiresAt int64  `json:"exp,omitempty"`
  Id        string `json:"jti,omitempty"`
  IssuedAt  int64  `json:"iat,omitempty"`
  Issuer    string `json:"iss,omitempty"`
  NotBefore int64  `json:"nbf,omitempty"`
  Subject   string `json:"sub,omitempty"`
}


其中 ExpiresAt 和 Issuer 分别是过期时间和签发者。

使用 jwt-go 库根据指定的算法生成 jwt token ,主要用到两个方法:


jwt.NewWithClaims 方法:


func jwt.NewWithClaims(method jwt.SigningMethod, claims jwt.Claims) *jwt.Token


jwt.NewWithClaims 方法根据 Claims 结构体创建 Token 示例。

参数 1 是 jwt.SigningMethod,

其中包含

jwt.SigningMethodHS256,

jwt.SigningMethodHS384,

jwt.SigningMethodHS512

三种 crypto.Hash 加密算法的方案。

参数 2 是 Claims,包含自定义类型和 StandardClaim,StandardClaim 嵌入在自定义类型中,以方便对标准声明进行编码,解析和验证。


SignedString 方法:


func (*jwt.Token).SignedString(key interface{}) (string, error)


SignedString 方法根据传入的空接口类型参数 key,返回完整的签名令牌。


示例代码:


func GenerateToken() (string, error) {
  nowTime := time.Now()
  expireTime := nowTime.Add(300 * time.Second)
  issuer := "frank"
  claims := MyCustomClaims{
    ID:       10001,
    Username: "frank",
    StandardClaims: jwt.StandardClaims{
      ExpiresAt: expireTime.Unix(),
      Issuer:    issuer,
    },
  }
  token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte("golang"))
  return token, err
}


03

解析 token


使用 jwt-go 库解析 token,主要用到两个方法,分别用通过与解析传入的 token 字符串,和根据 MyCustomClaims 结构体定义的相关属性要求进行校验。


jwt.ParseWithClaims 方法:


func jwt.ParseWithClaims(tokenString string, claims jwt.Claims, keyFunc jwt.Keyfunc) (*jwt.Token, error)


jwt.ParseWithClaims 方法用于解析鉴权的声明,返回 *jwt.Token。


Valid 方法用于校验鉴权的声明。


示例代码:


func ParseToken(token string) (*MyCustomClaims, error) {
  tokenClaims, err := jwt.ParseWithClaims(token, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
    return []byte("golang"), nil
  })
  if err != nil {
    return nil, err
  }
  if tokenClaims != nil {
    if claims, ok := tokenClaims.Claims.(*MyCustomClaims); ok && tokenClaims.Valid {
      return claims, nil
    }
  }
  return nil, err
}


04

总结


本文开头介绍了什么是 JWT,和怎么安装 jwt-go 库。然后通过生成 token 和解析 token 两个示例,介绍了其中需要用到的四个方法。jwt-go 库还有很多其他方法,限于篇幅,没有一一介绍。感兴趣的读者,可以阅读 jwt-go 库的文档进一步了解。





目录
相关文章
|
10月前
|
Java 编译器 Go
【Golang】(1)Go的运行流程步骤与包的概念
初次上手Go语言!先来了解它的运行流程吧! 在Go中对包的概念又有怎样不同的见解呢?
452 4
|
10月前
|
Java 编译器 Go
【Golang】(5)Go基础的进阶知识!带你认识迭代器与类型以及声明并使用接口与泛型!
好烦好烦好烦!你是否还在为弄不懂Go中的泛型和接口而烦恼?是否还在苦恼思考迭代器的运行方式和意义?本篇文章将带你了解Go的接口与泛型,还有迭代器的使用,附送类型断言的解释
419 3
|
10月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
452 2
|
机器学习/深度学习 存储 算法
【LeetCode 热题100】347:前 K 个高频元素(详细解析)(Go语言版)
这篇文章详细解析了力扣热题 347——前 K 个高频元素的三种解法:哈希表+小顶堆、哈希表+快速排序和哈希表+桶排序。每种方法都附有清晰的思路讲解和 Go 语言代码实现。小顶堆方法时间复杂度为 O(n log k),适合处理大规模数据;快速排序方法时间复杂度为 O(n log n),适用于数据量较小的场景;桶排序方法在特定条件下能达到线性时间复杂度 O(n)。文章通过对比分析,帮助读者根据实际需求选择最优解法,并提供了完整的代码示例,是一篇非常实用的算法学习资料。
881 90
|
11月前
|
Linux Go iOS开发
IDA 9.2 发布:Golang 改进、新 UI 组件、类型解析等
IDA Pro 9.2 (macOS, Linux, Windows) - 强大的反汇编程序、反编译器和多功能调试器
1620 0
|
存储 自然语言处理 算法
【LeetCode 热题100】208:实现 Trie (前缀树)(详细解析)(Go语言版)
本文详细解析了力扣热题 208——实现 Trie(前缀树)。Trie 是一种高效的树形数据结构,用于存储和检索字符串集合。文章通过插入、查找和前缀匹配三个核心操作,结合 Go 语言实现代码,清晰展示了 Trie 的工作原理。时间复杂度为 O(m),空间复杂度也为 O(m),其中 m 为字符串长度。此外,还探讨了 Trie 的变种及应用场景,如自动补全和词典查找等。适合初学者深入了解 Trie 结构及其实际用途。
614 14
|
SQL 运维 监控
高效定位 Go 应用问题:Go 可观测性功能深度解析
为进一步赋能用户在复杂场景下快速定位与解决问题,我们结合近期发布的一系列全新功能,精心梳理了一套从接入到问题发现、再到问题排查与精准定位的最佳实践指南。
|
存储 机器学习/深度学习 缓存
🚀 力扣热题 394:字符串解码(详细解析)(Go语言版)
文章提供了两种解法:栈结构和递归解法。栈解法通过维护数字栈与字符串栈,依次处理 `[` 和 `]`,构造解码结果;递归解法则利用函数调用逐层解析嵌套结构。两者时间复杂度均为 $O(n)$,空间复杂度也为 $O(n)$。栈解法直观易懂,适合初学者;递归解法优雅简洁,适合处理深度嵌套规则。掌握这两种方法,可灵活应对类似问题,提升解题能力。
570 11
|
Go 开发者
go-carbon v2.6.0 重大版本更新,轻量级、语义化、对开发者友好的 golang 时间处理库
carbon 是一个轻量级、语义化、对开发者友好的 Golang 时间处理库,提供了对时间穿越、时间差值、时间极值、时间判断、星座、星座、农历、儒略日 / 简化儒略日、波斯历 / 伊朗历的支持
377 3
|
前端开发 JavaScript Java
优雅草卓伊凡:全栈工程师并非盲目学语言,转型价值全解析
优雅草卓伊凡:全栈工程师并非盲目学语言,转型价值全解析
259 0
优雅草卓伊凡:全栈工程师并非盲目学语言,转型价值全解析

推荐镜像

更多