当前位置: 首页 > news >正文

【AI图像生成网站Golang】JWT认证与令牌桶算法

AI图像生成网站

目录

一、项目介绍

二、雪花算法

三、JWT认证与令牌桶算法

四、项目架构

五、图床上传与图像生成API搭建

六、项目测试与调试(等待更新)


三、JWT认证与令牌桶算法

在现代后端开发中,用户认证和接口限流是确保系统安全性和性能的两大关键要素。本文将基于实际代码,介绍 JWT 认证 和 令牌桶限流算法 的原理和实现。


1. JWT认证

JWT(JSON Web Token)是一种开放标准(RFC 7519),定义了一种紧凑的、自包含的方式,用于在各方之间安全地传输信息。这些信息经过签名验证后,可以信任其真实性。它通常用于用户认证场景,流程如下:

  1. 用户登录成功后,服务器生成一个JWT并返回给客户端。
  2. 客户端每次访问受保护的接口时,将JWT放入请求头中。
  3. 服务器解析JWT验证用户身份。

一个典型的JWT由三部分组成:

  • Header:描述加密算法类型(如 HS256)。
  • Payload(有效载荷):实际数据,例如用户信息和 Token 过期时间。
  • Signature:通过密钥和 Header、Payload 签名生成,用于验证数据的完整性。

        JWT 的标准声明只包含一些通用字段(如 expiat1),但在实际应用中,我们需要存储更多的业务数据,比如用户 ID 和用户名。
        在 JWT 中,Payload 就是 Token 的核心数据部分,用来存储那些需要在两方之间传递的信息。它包含了自定义的声明(Claims),例如用户的标识(user_id)或过期时间(exp)。Payload 不会被加密,但会被签名以保证数据的完整性。我们可以自定义结构体 MyClaims来实现自定义声明:

type MyClaims struct {UserID   uint64 `json:"user_id"`Username string `json:"username"`jwt.StandardClaims
}

之后,我们需要生成Access TokenRefresh Token来减少用户的重复登录行为,从而在保证安全性的同时提高交互体验,具体交互过程为:

在这里插入图片描述

用户登录阶段

  1. 用户在登录页面输入用户名和密码。
  2. 服务器验证用户的身份后,生成并返回:
    • 一个短期有效的 Access Token。
    • 一个长期有效的 Refresh Token。
  3. 客户端存储 Token(通常 Access Token 存在内存中,Refresh Token 存在安全存储区)。

生成 Access TokenRefresh Token 的函数如下:

// 定义Secret 用于加密的字符串
var mySecret = []byte("aidraw")func GenToken(userID uint64, username string) (aToken, rToken string, err error) {c := MyClaims{UserID:   userID,Username: username,StandardClaims: jwt.StandardClaims{ExpiresAt: time.Now().Add(AccessTokenExpireDuration).Unix(),Issuer:    "aidraw",},}aToken, err = jwt.NewWithClaims(jwt.SigningMethodHS256, c).SignedString(mySecret)rToken, err = jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.StandardClaims{ExpiresAt: time.Now().Add(RefreshTokenExpireDuration).Unix(),Issuer:    "aidraw",}).SignedString(mySecret)return
}

与网站交互阶段

  1. 初始请求:客户端将 Access Token 添加到每个请求的 HTTP 头部(Authorization: Bearer <Access Token>)。服务器解析 Token 并验证用户身份。

解析Token的代码为:

func keyFunc(_ *jwt.Token) (i interface{}, err error) {return mySecret, nil
}// ParseToken 解析Token.
func ParseToken(tokenString string) (claims *MyClaims, err error) {claims = new(MyClaims)token, err := jwt.ParseWithClaims(tokenString, claims, keyFunc)if err != nil {return}if !token.Valid {err = errors.New("invalid token")}return
}
  1. Access Token 过期:当 Access Token 失效时,客户端会用 Refresh Token 请求新的 Access Token。

刷新Token的代码为:

func RefreshToken(aToken, rToken string) (newAToken, newRToken string, err error) {// 验证 Refresh Token 是否有效if _, err = jwt.Parse(rToken, keyFunc); err != nil {return}// 解析 Access Token 提取用户信息var claims MyClaims_, err = jwt.ParseWithClaims(aToken, &claims, keyFunc)v, _ := err.(*jwt.ValidationError)// 如果 Access Token 是过期错误,生成新的 Tokenif v.Errors == jwt.ValidationErrorExpired {return GenToken(claims.UserID, claims.Username)}return
}
  1. 刷新 Token 过程
    1. 客户端发送 Refresh Token 给 /refresh_token API。
    2. 服务器验证 Refresh Token 是否有效。
    3. 如果 Refresh Token 合法且未过期,生成新的 Access Token 和 新的 Refresh Token。

2. 基于 JWT 的认证中间件

为了在路由处理函数中提取用户信息,我们需要实现一个基于 JWT 的 Gin 中间件:

  1. 从请求头的 Authorization 字段提取 Token。
  2. 验证 Token 的合法性。
  3. 将解析出的用户信息保存到上下文中,供后续的路由函数使用。
    代码如下:
package middlewaresimport ("backend/controller""backend/pkg/jwt""fmt""strings""github.com/gin-gonic/gin"
)// JWTAuthMiddleware 基于JWT的认证中间件
func JWTAuthMiddleware() func(c *gin.Context) {return func(c *gin.Context) {// 客户端携带Token有三种方式 1.放在请求头 2.放在请求体 3.放在URI// 这里假设Token放在Header的Authorization中,并使用Bearer开头// 这里的具体实现方式要依据你的实际业务情况决定authHeader := c.Request.Header.Get("Authorization")if authHeader == "" {controller.ResponseErrorWithMsg(c, controller.CodeInvalidToken, "请求头缺少Auth Token")c.Abort()return}// 按空格分割parts := strings.SplitN(authHeader, " ", 2)if !(len(parts) == 2) {controller.ResponseErrorWithMsg(c, controller.CodeInvalidToken, "Token格式不对")c.Abort()return}// parts[1]是获取到的tokenString,我们使用之前定义好的解析JWT的函数来解析它mc, err := jwt.ParseToken(parts[1])if err != nil {fmt.Println(err)controller.ResponseError(c, controller.CodeInvalidToken)c.Abort()return}// 将当前请求的userID信息保存到请求的上下文c上c.Set(controller.ContextUserIDKey, mc.UserID)c.Next() // 后续的处理函数可以用过c.Get(ContextUserIDKey)来获取当前请求的用户信息}
}

3. 令牌桶限流算法

在现代 Web 开发中,流量控制是确保系统稳定性的重要手段之一。令牌桶算法(Token Bucket Algorithm)是一种广泛使用的限流算法,可以高效处理突发流量。其核心思想如下:

  • 固定速率发放令牌:按照指定的时间间隔,将令牌加入桶中。
  • 允许突发流量:桶有一个固定的容量,当令牌数量达到容量时,新的令牌会被丢弃。
  • 请求消耗令牌:每次请求需要消耗一定数量的令牌,如果桶中没有足够的令牌,请求将被拒绝或等待。

适用于需要控制 API 的访问频率、允许短时间内的突发请求(如秒杀活动)的场景。

令牌桶中间件实现

实现令牌桶限流中间件代码如下:

package middlewaresimport ("github.com/gin-gonic/gin""github.com/juju/ratelimit""net/http""time"
)// RateLimitMiddleware 创建指定填充速率和容量大小的令牌桶
func RateLimitMiddleware(fillInterval time.Duration, cap int64) func(c *gin.Context) {// 创建令牌桶bucket := ratelimit.NewBucket(fillInterval, cap)return func(c *gin.Context) {// 检查是否能够获取令牌if bucket.TakeAvailable(1) == 0 {// 如果令牌不足,返回限流提示c.String(http.StatusOK, "rate limit...")c.Abort() // 中断请求return}// 如果获取到令牌,继续处理请求c.Next()}
}

参数说明:

  • fillInterval:令牌添加的时间间隔。
  • cap:桶的容量。

调用代码

本项目通过在所有路由之前设置令牌桶中间件实现了全局限流:

//初始化 gin Engine  新建一个没有任何默认中间件的路由
r := gin.New()
//设置中间件
r.Use(middlewares.RateLimitMiddleware(2*time.Second, 40), // 每两秒钟添加十个令牌  全局限流
)r.LoadHTMLFiles("templates/index.html") // 加载html

  1. expiat 是 JWT 中的标准声明字段(Standard Claims)。这些字段遵循 RFC 7519 的规范,表示 Token 的时间相关信息。
            exp(Expiration Time):表示 Token 的过期时间。单位为秒,自 Unix 时间纪元(1970-01-01 00:00:00 UTC)以来的秒数。当客户端请求到达服务器时,如果当前时间大于 exp,Token 会被判定为无效。例如1699844000 表示过期时间是 2023-11-12 10:00:00 UTC。
            iat(Issued At):表示 Token 签发的时间。单位同样为秒,用于标识 Token 的创建时间。它可以用来防止 Token 重放攻击(Replay Attack)。 ↩︎

相关文章:

【AI图像生成网站Golang】JWT认证与令牌桶算法

AI图像生成网站 目录 一、项目介绍 二、雪花算法 三、JWT认证与令牌桶算法 四、项目架构 五、图床上传与图像生成API搭建 六、项目测试与调试(等待更新) 三、JWT认证与令牌桶算法 在现代后端开发中&#xff0c;用户认证和接口限流是确保系统安全性和性能的两大关键要素…...

关于强化学习的一份介绍

在这篇文章中&#xff0c;我将介绍与强化学习有关的一些东西&#xff0c;具体包括相关概念、k-摇臂机、强化学习的种类等。 一、基本概念 所谓强化学习就是去学习&#xff1a;做什么才能使得数值化的收益信号最大化。学习者不会被告知应该采取什么动作&#xff0c;而是必须通…...

Python3.11.9+selenium,获取图片验证码以及输入验证码数字

Python3.11.9+selenium,获取图片验证码以及输入验证码数字 1、遇到问题:登录或修改密码需要验证码 2、解决办法: 2.1、安装ddddocr pip install ddddocr 2.2、解析验证码函数 import ddddocr def get_capcha_text():#获取验证码图片ele_pic = driver.find_element(By.XPAT…...

Flutter:事件队列,异步操作,链式调用。

Flutter分2种队列 1、事件队列&#xff1a;异步的处理&#xff0c;按顺序执行 import package:flutter/material.dart; main(){testFuture1();testFuture2(); }// 按顺序执行处理A->B->C testFuture1() async {Future((){return 任务A;}).then((value){print(按顺序执行&…...

从零开始学习 sg200x 多核开发之 eth0 自动使能并配置静态IP

前文提到 sophpi 默认没有使能有线网络&#xff0c;需要手工配置&#xff1a; [rootsg200x]~# ifconfig eth0 up [rootsg200x]~# udhcpc -i eth0 [rootsg200x]~# ifconfig eth0 Link encap:Ethernet HWaddr EA:BD:18:08:1E:87 inet addr:192.168.188.142 Bcast:192.1…...

《TCP/IP网络编程》学习笔记 | Chapter 11:进程间通信

《TCP/IP网络编程》学习笔记 | Chapter 11&#xff1a;进程间通信 《TCP/IP网络编程》学习笔记 | Chapter 11&#xff1a;进程间通信进程间通信的基本概念通过管道实现进程间通信通过管道进行进程间双向通信 运用进程间通信习题&#xff08;1&#xff09;什么是进程间通信&…...

开源模型应用落地-qwen模型小试-Qwen2.5-7B-Instruct-tool usage入门-集成心知天气(二)

一、前言 Qwen-Agent 是一个利用开源语言模型Qwen的工具使用、规划和记忆功能的框架。其模块化设计允许开发人员创建具有特定功能的定制代理,为各种应用程序提供了坚实的基础。同时,开发者可以利用 Qwen-Agent 的原子组件构建智能代理,以理解和响应用户查询。 本篇将介绍如何…...

通过声纹或者声波来切分一段音频

通过声纹识别或基于声波特征的模型&#xff0c;确实可以帮助切分一段音频并区分出不同讲话者的语音片段。这种技术被称为 基于声纹的语音分割 或 基于说话人识别的音频分割。其核心原理是利用每个说话者的 声纹特征&#xff08;即每个人独特的语音特征&#xff09;来识别和切分…...

sql专场练习(二)(16-20)完结

第十六题 用户登录日志表为user_id,log_id,session_id,visit_time create table sql2_16(user_id int,log_id int,session_id int,visit_time string );没有数据 visit_time 时间格式为2024-11-15 用sql查询近30天每天平均登录用户数量 with t1 as (select visit_time,coun…...

[ 网络安全介绍 2 ] 网络安全发展现状

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…...

《基于Oracle的SQL优化》读书笔记

查看执行计划set autotrace traceonly explain在当前session中将优化器模式改为RULE。alter session set optimizer_modeRULE;统计信息存储在oracle的数据字典里&#xff0c;且从多个维度描述了oracle数据库里相关对象的实际数据量&#xff0c;实际数据分布等详细信息。 -- 对…...

零基础利用实战项目学会Pytorch

目录 pytorch简介 1.线性回归 2.数据类型 2.1数据类型检验 2.2Dimension0/Rank0 2.3 Dim1/Rank1 2.4 Dim2/Rank2 3.一些方法 4.Pytorch完成分类任务 4.1模型参数 4.2 前向传播 4.3训练以及验证 4.4 三行搞定&#xff01; 4.5 准确率 5、Pytorch完成回归任务 5.…...

Go八股(Ⅵ)Goroutine 以及其中的锁和思想

Goroutine与并发编程的关系 什么是并发 是指多个任务在同一时间段内进行处理&#xff0c;但不一定是在同一时刻执行。并发强调的是“结构上的并行性”&#xff0c;也就是说&#xff0c;程序能够在一个时间端内同时处理多个任务&#xff0c;但是这些任务可能是交替进行的。例如…...

向潜在安全信息和事件管理 SIEM 提供商提出的六个问题

收集和解读数据洞察以制定可用的解决方案是强大网络安全策略的基础。然而&#xff0c;组织正淹没在数据中&#xff0c;这使得这项任务变得复杂。 传统的安全信息和事件管理 ( SIEM ) 工具是组织尝试使用的一种方法&#xff0c;但由于成本、资源和可扩展性等几个原因&#xff0…...

蓝桥杯每日真题 - 第15天

题目&#xff1a;&#xff08;钟表&#xff09; 题目描述&#xff08;13届 C&C B组B题&#xff09; 解题思路&#xff1a; 理解钟表指针的运动&#xff1a; 秒针每分钟转一圈&#xff0c;即每秒转6度。 分针每小时转一圈&#xff0c;即每分钟转6度。 时针每12小时转一圈…...

Python的Matplotlib

介绍&#xff1a; Matplotlib 是一个非常强大的 Python 绘图库&#xff0c;支持多种不同类型的图表。以下是 Matplotlib 支持的一些常见图表类型&#xff1a; 前情提要&#xff1a; from matplotlib import rcParams# 设置支持中文的字体 rcParams[font.sans-serif] [SimHei…...

Python数据分析:分组转换transform方法

大家好&#xff0c;在数据分析中&#xff0c;需要对数据进行分组统计与计算&#xff0c;Pandas的groupby功能提供了强大的分组功能。transform方法是groupby中常用的转换方法之一&#xff0c;它允许在分组的基础上进行灵活的转换和计算&#xff0c;并将结果与原始数据保持相同的…...

高效灵活的Django URL配置与反向URL实现方案

高效灵活的Django URL配置与反向URL实现方案 目录 &#x1f4d1; 1. 基本的Django URL配置及反向URL的实现 &#x1f527; 2. 使用path()替代re_path()配置URL的优势与劣势 &#x1f6e0;️ 3. 使用URL命名空间&#xff08;namespace&#xff09;提高URL管理的可维护性 &…...

深入探讨 MySQL 配置与优化:从零到生产环境的最佳实践20241112

深入探讨 MySQL 配置与优化&#xff1a;从零到生产环境的最佳实践 引言 MySQL 是全球最受欢迎的开源关系型数据库之一&#xff0c;其高性能、灵活性和广泛的社区支持使其成为无数开发者的首选。然而&#xff0c;部署一台高效、稳定的 MySQL 实例并非易事。本文将结合一个实际…...

Java-Redisson分布式锁+自定义注解+AOP的方式来实现后台防止重复请求扩展

1. 添加依赖 首先,在项目的pom.xml文件中添加Redisson和Spring AOP的相关依赖: <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.16.8</version> </dependency> <dependency…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...