首页 > 其他分享 >【JWT】jwt认证机制认识与理解,go案例实现

【JWT】jwt认证机制认识与理解,go案例实现

时间:2025-01-22 22:03:59浏览次数:3  
标签:err JWT jwt token Token go Payload

JWT 认证机制

JWT(JSON Web Token)是一种轻量级的身份认证机制,广泛应用于现代 Web 开发中,尤其是在分布式系统和微服务中。它通过签名技术确保数据的真实性和完整性。


1. JWT 的基本结构

JWT 是一个由三部分组成的字符串(头部,负载,签名):

Header.Payload.Signature
1.1 Header(头部)
  • 作用:声明 Token 的元信息,如签名算法和 Token 类型。
  • 典型结构
    {
      "alg": "HS256", // 签名算法,如 HMAC SHA256
      "typ": "JWT"    // Token 类型
    }
    
  • Base64 编码:经过 Base64 编码后,生成 Header 部分。
1.2 Payload(负载)
  • 作用
  • Payload 部分是一个 JSON 对象,用来存放实际需要传递的数据。
  • 存储声明(claims),包括用户信息和元数据。
  • 三种声明分类
    • 注册声明(Registered Claims)
      标准字段,JWT 规定了7个官方字段,供选用。
      • iss (issuer):签发人
      • exp (expiration time):过期时间
      • sub (subject):主题
      • aud (audience):受众
      • nbf (Not Before):生效时间
      • iat (Issued At):签发时间
      • jti (JWT ID):编号
    • 公开声明(Public Claims):自定义数据字段,如 user_idrole
    • 私有声明(Private Claims):仅供双方约定的字段。
  • 典型结构
    {
      "sub": "1234567890",
      "name": "John Doe",
      "admin": true,
      "iat": 1516239022 // 签发时间
    }
    
  • Base64 编码:经过 Base64 编码后,生成 Payload 部分。
1.3 Signature(签名)
  • 作用:保证 Token 的完整性和不可篡改。
  • 生成方式
    HMACSHA256(
      base64UrlEncode(header) + "." + base64UrlEncode(payload),
      secret
    )
    
    • 使用 Header 和 Payload 的 Base64 编码内容生成签名。Base64URL与Base64算法类似,Base64中+、/和= 在URL中有特殊含义,因此Base64URL 对它们做了处理
    • secret 是服务器端的私钥,仅服务端可知。

JWT 是怎么工作的?

JWT 的工作流程简单,可以分为两步:生成 Token验证 Token

1. 生成 Token
  1. 用户登录时,服务器验证用户名和密码。
  2. 验证通过后,服务器根据用户信息生成 JWT。
  3. 把这个 Token 返回给客户端,客户端存起来(如 localStoragecookie)。
2. 验证 Token
  1. 客户端每次请求时,把 Token 放到 HTTP 请求头里:
   Authorization: Bearer <Token>
  1. 服务器拿到 Token 后,检查:
  • 签名:确认 Token 没被改过。
  • 过期时间:检查 exp 是否有效。
  1. 验证通过后,服务器允许访问资源。

JWT 的优点

  1. 无状态:服务器不用存储会话信息,特别适合分布式系统。
  2. 高效:Token 放在客户端,服务器验证时直接解析,无需查询数据库。
  3. 灵活:可以在 Payload 中添加任何需要的用户信息。

JWT 的缺点

  1. Token 无法主动失效
  • 如果用户登出或权限变更,旧 Token 仍然有效,除非改签名密钥。
  1. Token 体积较大
  • 包含 Header、Payload 和签名,可能会影响网络性能。
  1. JWT默认不加密,在不加密的情况下,不要携带敏感数据
  • JWT 的组成部分(Header、Payload、Signature)是以 Base64 编码存储的,而 Base64 不是加密,只是编码。这意味着任何拿到 JWT 的人都可以轻松解码出 Header 和 Payload,看到里面的内容。

例子:日常生活中的 JWT

假设你去一个游乐园玩,买了一张票(JWT)。

  • 票上的信息(Payload):你的姓名、有效时间、可玩的项目。
  • 防伪标识(Signature):游乐园的官方签名,防止伪造票。

你拿着票(Token)可以自由进入项目(资源)。
如果票到期(过期时间),你需要重新购买(重新登录)。


4. 安全注意事项

  1. 使用 HTTPS
    • 确保 Token 传输过程中不会被窃听。
  2. 设置合理的过期时间
    • 控制 Token 的有效期,减少风险。
  3. 定期更换密钥
    • 避免长期使用同一密钥。
  4. Token 存储位置
    • 避免将 Token 存储在不安全的位置(如 localStorage)。
  5. Token 黑名单
    • 通过数据库记录已失效的 Token 实现黑名单机制,弥补无状态的不足。

5. 实现示例(Go 语言)

依赖安装

使用 github.com/golang-jwt/jwt/v4 包:

go get github.com/golang-jwt/jwt/v4
代码实现
package main

import (
	"fmt"
	"time"

	"github.com/golang-jwt/jwt/v4"
)

var secretKey = []byte("my_secret_key") // 密钥

// 生成 JWT
func GenerateJWT(userID string) (string, error) {
	claims := jwt.MapClaims{
		"user_id": userID,
		"exp":     time.Now().Add(time.Hour * 2).Unix(), // 过期时间
		"iat":     time.Now().Unix(),                   // 签发时间
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	return token.SignedString(secretKey)
}

// 验证 JWT
func ValidateJWT(tokenString string) (string, error) {
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("签名方法不匹配")
		}
		return secretKey, nil
	})

	if err != nil {
		return "", err
	}

	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		return claims["user_id"].(string), nil
	}

	return "", fmt.Errorf("无效的 Token")
}

func main() {
	// 生成 Token
	token, err := GenerateJWT("12345")
	if err != nil {
		fmt.Println("生成 Token 失败:", err)
		return
	}
	fmt.Println("生成的 Token:", token)

	// 验证 Token
	userID, err := ValidateJWT(token)
	if err != nil {
		fmt.Println("验证 Token 失败:", err)
		return
	}
	fmt.Println("验证成功,用户 ID:", userID)
}

https://github.com/0voice

标签:err,JWT,jwt,token,Token,go,Payload
From: https://blog.csdn.net/m0_74282926/article/details/145287785

相关文章

  • Go学习:多个变量或常量定义
    目录1.不同类型变量的声明(定义)2. 不同类型常量的声明(定义)1.不同类型变量的声明(定义)传统方法//不同类型变量的声明(定义)   varaint   varbfloat64    a,b=10,3.14packagemainimport"fmt"funcmain(){ //不同类型变量的声明(定义......
  • 路径规划之启发式算法之二十七:果蝇优化算法(Fruit Fly Optimization Algorithm,FOA)
            果蝇优化算法(FruitFlyOptimizationAlgorithm,FOA)是一种基于果蝇觅食行为的仿生学原理而提出的新兴群体智能优化算法。是众多群体智能算法之一,可看我的文章:仿生的群体智能算法总结之二(十种)_群体仿生智能-CSDN博客仿生的群体智能算法总结之二(十种)_群体仿生智......
  • 【Golang/gRPC/Nacos】在golang中将gRPC和Nacos结合使用
    Nacos与gRPC前言关于这部分,前段时间我在看文档以及视频教程的时候,怎么都想不明白,到底为什么要用gRPC是什么,他在项目中应该充当什么样的角色?Nacos又是如何和他结合的?于是我就决定去看看一些小项目是如何实现的这个功能,现在将我最近学到的分享给大家。正文在正文开始之前......
  • 本地网站搭建之go语言环境安装
    时间:2025/1/22操作系统:win11开发工具选择:VSCcode1、下载go语言安装包,地址[https://golang.google.cn/dl/]2、配置环境变量路径为go安装路径配置完成后可以在命令行中验证,能够识别go命令即为配置成功3、换源这里推荐[https://www.goproxy.io/zh/]和https://goproxy.cn......
  • VSCode使用之go语言配置
    时间:2025/1/22扩展:go目的:支持go语言,方便安装其他必备插件安装该扩展包后可以执行该扩展包提供的命令Go:Install/UpdateTools来进一步扩展go工具执行命令的窗口可以通过Ctrol+Shift+P调出点击后会出现很多选项,可以根据自己需要勾选然后点击确定,等待下载安装,一般情况下......
  • 第二篇 Django的模版各功能示例 以及 初学者常见问题
    目录1、Django模版环境配置2、本项目遇到的问题:UsingtheURLconfdefinedinHelloWorld.urls,DjangotriedtheseURLpatterns,inthisorder:3、Django模版常用语法规则变量1、Django模版环境配置我们接着上一篇文章项目将在HelloWorld目录底下创建templat......
  • typechoTohugo
    go实现typecho转换为mdpackagemainimport( "database/sql" "fmt" "os" "strings" "time" _"github.com/go-sql-driver/mysql")funcmain(){ //配置数据库连接信息 dbHost:="localhost"......
  • 【Django DRF Apps】【文件上传】【断点上传】从零搭建一个普通文件上传,断点续传的App
    DjangoDRF应用搭建文档:普通文件上传与大文件断点上传本文档将指导你从零搭建一个支持普通文件上传和大文件断点上传功能的DjangoDRF应用。我们将通过两部分内容进行说明:普通文件上传功能和分片上传功能。功能点说明普通文件上传:处理普通文件上传,支持根据文件内容......
  • 《零基础Go语言算法实战》【题目 7-4】删除数组重复项,使每个元素只出现一次并返回新的
    《零基础Go语言算法实战》【题目7-4】删除数组重复项,使每个元素只出现一次并返回新的长度给定一个排序数组array,就地删除重复项,使每个元素只出现一次并返回新的长度。不要为另一个数组分配额外的空间,开发者必须通过使用空间复杂度为O(1)的额外内存就地修改输入数组来做到......
  • GoAccess : 高效开源的Web日志分析工具
    什么是GoAccessGoAccess是一款高效、开源的Web日志分析工具,专为快速解析和可视化Apache、Nginx等Web服务器的访问日志而设计。它通过命令行界面提供实时分析功能,能够生成详细的访问统计、访客排名、页面请求等关键信息,并支持将分析结果导出为HTML、JSON、CSV等多种格式。GoAccess......