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月前
|
数据采集 数据挖掘 测试技术
Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析
本文对比了Python与Go在爬虫开发中的特点。Python凭借Scrapy等框架在开发效率和易用性上占优,适合快速开发与中小型项目;而Go凭借高并发和高性能优势,适用于大规模、长期运行的爬虫服务。文章通过代码示例和性能测试,分析了两者在并发能力、错误处理、部署维护等方面的差异,并探讨了未来融合发展的趋势。
1075 0
|
8月前
|
Cloud Native 安全 Java
Go语言深度解析:从入门到精通的完整指南
🌟蒋星熠Jaxonic,Go语言探索者。深耕云计算、微服务与并发编程,以代码为笔,在二进制星河中书写极客诗篇。分享Go核心原理、性能优化与实战架构,助力开发者掌握云原生时代利器。#Go语言 #并发编程 #性能优化
676 43
Go语言深度解析:从入门到精通的完整指南
|
算法 Go 索引
【LeetCode 热题100】45:跳跃游戏 II(详细解析)(Go语言版)
本文详细解析了力扣第45题“跳跃游戏II”的三种解法:贪心算法、动态规划和反向贪心。贪心算法通过选择每一步能跳到的最远位置,实现O(n)时间复杂度与O(1)空间复杂度,是面试首选;动态规划以自底向上的方式构建状态转移方程,适合初学者理解但效率较低;反向贪心从终点逆向寻找最优跳点,逻辑清晰但性能欠佳。文章对比了各方法的优劣,并提供了Go语言代码实现,助你掌握最小跳跃次数问题的核心技巧。
570 15
|
8月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
411 2
|
9月前
|
Cloud Native 安全 Java
Go语言深度解析:从入门到精通的完整指南
🌟 蒋星熠Jaxonic,执着的星际旅人,用Go语言编写代码诗篇。🚀 Go语言以简洁、高效、并发为核心,助力云计算与微服务革新。📚 本文详解Go语法、并发模型、性能优化与实战案例,助你掌握现代编程精髓。🌌 从goroutine到channel,从内存优化到高并发架构,全面解析Go的强大力量。🔧 实战构建高性能Web服务,展现Go在云原生时代的无限可能。✨ 附技术对比、最佳实践与生态全景,带你踏上Go语言的星辰征途。#Go语言 #并发编程 #云原生 #性能优化
|
12月前
|
存储 设计模式 安全
Go 语言单例模式全解析:从青铜到王者段位的实现方案
单例模式确保一个类只有一个实例,并提供全局访问点,适用于日志、配置管理、数据库连接池等场景。在 Go 中,常用实现方式包括懒汉模式、饿汉模式、双重检查锁定,最佳实践是使用 `sync.Once`,它并发安全、简洁高效。本文详解各种实现方式的优缺点,并提供代码示例与最佳应用建议。
408 5
|
10月前
|
缓存 监控 安全
告别缓存击穿!Go 语言中的防并发神器:singleflight 包深度解析
在高并发场景中,多个请求同时访问同一资源易导致缓存击穿、数据库压力过大。Go 语言提供的 `singleflight` 包可将相同 key 的请求合并,仅执行一次实际操作,其余请求共享结果,有效降低系统负载。本文详解其原理、实现及典型应用场景,并附示例代码,助你掌握高并发优化技巧。
743 0
|
10月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
存储 算法 Go
【LeetCode 热题100】17:电话号码的字母组合(详细解析)(Go语言版)
LeetCode 17题解题思路采用回溯算法,通过递归构建所有可能的组合。关键点包括:每位数字对应多个字母,依次尝试;递归构建下一个字符;递归出口为组合长度等于输入数字长度。Go语言实现中,使用map存储数字到字母的映射,通过回溯函数递归生成组合。时间复杂度为O(3^n * 4^m),空间复杂度为O(n)。类似题目包括括号生成、组合、全排列等。掌握回溯法的核心思想,能够解决多种排列组合问题。
548 11
|
Go
【LeetCode 热题100】155:最小栈(详细解析)(Go语言版)
本文详细解析了力扣热题155:最小栈的解题思路与实现方法。题目要求设计一个支持 push、核心思路是使用辅助栈法,通过两个栈(主栈和辅助栈)来维护当前栈中的最小值。具体操作包括:push 时同步更新辅助栈,pop 时检查是否需要弹出辅助栈的栈顶,getMin 时直接返回辅助栈的栈顶。文章还提供了 Go 语言的实现代码,并对复杂度进行了分析。此外,还介绍了单栈 + 差值记录法的进阶思路,并总结了常见易错点,如 pop 操作时忘记同步弹出辅助栈等。
452 6

推荐镜像

更多