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

Gin框架操作指南08:日志与安全

官方文档地址(中文):https://gin-gonic.com/zh-cn/docs/
注:本教程采用工作区机制,所以一个项目下载了Gin框架,其余项目就无需重复下载,想了解的读者可阅读第一节:Gin操作指南:开山篇。
本节演示日志与安全相关的API,包括定义路由日志的格式;如何记录日志;安全页眉;使用BasicAuth中间件;使用HTTP方法。其中控制日志输出颜色就是将gin.DisableConsoleColor()替换为gin.ForceConsoleColor(),读者可自行尝试,本文不做演示。在开始之前,我们需要在”04日志与安全“目录下打开命令行,执行如下命令来创建子目录:

mkdir 定义路由日志的格式 如何记录日志 安全页眉 使用BasicAuth中间件 使用HTTP方法

目录

    • 一、定义路由日志的格式
    • 二、如何记录日志
    • 三、安全页眉
    • 四、使用BasicAuth中间件
    • 五、使用HTTP方法

一、定义路由日志的格式

默认的路由日志格式:

[GIN-debug] POST   /foo                      --> main.main.func1 (3 handlers)
[GIN-debug] GET    /bar                      --> main.main.func2 (3 handlers)
[GIN-debug] GET    /status                   --> main.main.func3 (3 handlers)

如果你想要以指定的格式(例如 JSON,key values 或其他格式)记录信息,则可以使用 gin.DebugPrintRouteFunc 指定格式。 在下面的示例中,我们使用标准日志包记录所有路由,但你可以使用其他满足你需求的日志工具。

package mainimport ("log"      // 导入标准日志包,用于记录日志信息"net/http" // 导入 net/http 包,用于 HTTP 状态码和相关类型"github.com/gin-gonic/gin" // 导入 Gin 框架
)func main() {r := gin.Default() // 创建一个默认的 Gin 路由引擎// 自定义路由打印函数,以指定的格式记录路由信息gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {// 使用标准日志包打印每个路由的 HTTP 方法、绝对路径、处理函数名称和处理函数数量log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)}// 定义 POST 路由 /foor.POST("/foo", func(c *gin.Context) {// 返回 JSON 响应,内容为 "foo" 和 HTTP 状态码 200c.JSON(http.StatusOK, "foo")})// 定义 GET 路由 /barr.GET("/bar", func(c *gin.Context) {// 返回 JSON 响应,内容为 "bar" 和 HTTP 状态码 200c.JSON(http.StatusOK, "bar")})// 定义 GET 路由 /statusr.GET("/status", func(c *gin.Context) {// 返回 JSON 响应,内容为 "ok" 和 HTTP 状态码 200c.JSON(http.StatusOK, "ok")})// 监听并在 0.0.0.0:8080 上启动服务r.Run() // 启动 Gin 路由引擎
}

效果
GET测试
在这里插入图片描述

POST测试
在这里插入图片描述

二、如何记录日志

package mainimport ("io" // 导入 io 包,用于多路写入"os" // 导入 os 包,用于文件操作"github.com/gin-gonic/gin" // 导入 Gin 框架
)func main() {// 禁用控制台颜色,将日志写入文件时不需要控制台颜色。gin.DisableConsoleColor()// 创建一个文件用于保存日志,文件名为 "gin.log"f, err := os.Create("gin.log")if err != nil {panic(err) // 如果文件创建失败,抛出错误}// 设置 Gin 的默认写入器,将日志写入到刚创建的文件中gin.DefaultWriter = io.MultiWriter(f)// 如果需要同时将日志写入文件和控制台,请使用以下代码。// gin.DefaultWriter = io.MultiWriter(f, os.Stdout)// 创建默认的 Gin 路由引擎router := gin.Default()// 定义 GET 路由 /pingrouter.GET("/ping", func(c *gin.Context) {// 返回字符串 "pong" 和 HTTP 状态码 200c.String(200, "pong")})// 监听并在 0.0.0.0:8080 上启动服务router.Run(":8080") // 启动 Gin 路由引擎
}

效果
注意,启动后控制台是没有输出的,因为屏蔽了颜色,但go.mod旁边会出现gin.log文件,打开即可看到控制台的输出
在这里插入图片描述
打开浏览器,测试,log文件会变化
在这里插入图片描述

三、安全页眉

使用安全标头保护网络应用程序免受常见安全漏洞的攻击非常重要。本示例将向您展示如何在 Gin 应用程序中添加安全标头,以及如何避免与主机标头注入相关的攻击(SSRF、开放重定向)。

package mainimport ("net/http" // 导入 net/http 包,用于 HTTP 相关的功能"github.com/gin-gonic/gin" // 导入 Gin 框架
)func main() {// 创建一个默认的 Gin 路由引擎r := gin.Default()// 设置期望的主机头部(Host Header)expectedHost := "localhost:8080"// 设置安全标头的中间件r.Use(func(c *gin.Context) {// 检查请求中的 Host 是否符合预期if c.Request.Host != expectedHost {// 如果 Host 不正确,返回 400 错误并结束请求c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})return}// 设置安全标头以保护应用程序c.Header("X-Frame-Options", "DENY")                                                                                                                                    // 防止点击劫持c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';") // 防止跨站脚本攻击c.Header("X-XSS-Protection", "1; mode=block")                                                                                                                          // 启用 XSS 保护c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")                                                                                  // 强制使用 HTTPSc.Header("Referrer-Policy", "strict-origin")                                                                                                                           // 控制引用来源c.Header("X-Content-Type-Options", "nosniff")                                                                                                                          // 防止 MIME 类型嗅探c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")                 // 控制特定功能的权限c.Next()                                                                                                                                                               // 继续处理请求})// 定义 GET 路由 /pingr.GET("/ping", func(c *gin.Context) {// 返回 JSON 响应,包含 "pong" 消息c.JSON(200, gin.H{"message": "pong", // 消息内容})})// 启动服务,监听 0.0.0.0:8080r.Run() // listen and serve on 0.0.0.0:8080
}

打开postman,输入http://localhost:8080/ping,此时直接点send,或者随意设置headers中的key和value,只要key不是host(不区分大小写),均能正常输出。但如果在headers中设置了key为host(不区分大小写),那么value就必须是代码中设置好的值,这里是localhost:8080,否则出错,如图:
在这里插入图片描述

四、使用BasicAuth中间件

package mainimport ("net/http""github.com/gin-gonic/gin"
)// 模拟一些私人数据,使用 map 结构存储用户的私人信息
var secrets = gin.H{"foo":    gin.H{"email": "foo@bar.com", "phone": "123433"},     // 用户 foo 的私人信息"austin": gin.H{"email": "austin@example.com", "phone": "666"}, // 用户 austin 的私人信息"lena":   gin.H{"email": "lena@guapa.com", "phone": "523443"},  // 用户 lena 的私人信息
}func main() {r := gin.Default() // 创建一个默认的 Gin 路由器// 路由组使用 gin.BasicAuth() 中间件,保护 /admin 路径// gin.Accounts 是 map[string]string 的一种快捷方式,设置用户和密码authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{"foo":    "bar",    // 用户 foo 的密码"austin": "1234",   // 用户 austin 的密码"lena":   "hello2", // 用户 lena 的密码"manu":   "4321",   // 用户 manu 的密码}))// /admin/secrets 端点处理,只有经过 Basic Auth 验证的用户可以访问// 当用户访问 "localhost:8080/admin/secrets" 时,将触发此处理函数authorized.GET("/secrets", func(c *gin.Context) {// 获取当前用户的信息,它是由 BasicAuth 中间件设置的user := c.MustGet(gin.AuthUserKey).(string)if secret, ok := secrets[user]; ok {// 如果找到了用户的私人信息,返回该信息c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})} else {// 如果未找到用户的私人信息,返回默认信息c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})}})// 监听并在 0.0.0.0:8080 上启动服务,等待请求r.Run(":8080")
}

效果
在这里插入图片描述

五、使用HTTP方法

package mainimport ("net/http""github.com/gin-gonic/gin"
)// 获取请求的处理函数
func getting(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "GET request successful"})
}// 处理 POST 请求的处理函数
func posting(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "POST request successful"})
}// 处理 PUT 请求的处理函数
func putting(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "PUT request successful"})
}// 处理 DELETE 请求的处理函数
func deleting(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "DELETE request successful"})
}// 处理 PATCH 请求的处理函数
func patching(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "PATCH request successful"})
}// 处理 HEAD 请求的处理函数
func head(c *gin.Context) {// HEAD 请求只返回状态和头部,不返回请求体c.Status(http.StatusOK) // 返回状态码 200
}// 处理 OPTIONS 请求的处理函数
func options(c *gin.Context) {// OPTIONS 请求返回允许的 HTTP 方法c.JSON(http.StatusOK, gin.H{"methods": "GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS"})
}func main() {// 禁用控制台颜色// gin.DisableConsoleColor()// 使用默认中间件(logger 和 recovery 中间件)创建 gin 路由router := gin.Default()// 定义各个 HTTP 方法的路由及其处理函数router.GET("/someGet", getting)         // 处理 GET 请求router.POST("/somePost", posting)       // 处理 POST 请求router.PUT("/somePut", putting)         // 处理 PUT 请求router.DELETE("/someDelete", deleting)  // 处理 DELETE 请求router.PATCH("/somePatch", patching)    // 处理 PATCH 请求router.HEAD("/someHead", head)          // 处理 HEAD 请求router.OPTIONS("/someOptions", options) // 处理 OPTIONS 请求// 默认在 8080 端口启动服务,除非定义了一个 PORT 的环境变量。router.Run() // 启动服务并监听端口// router.Run(":3000") // 如果需要硬编码端口号,可以取消注释这一行
}

效果
使用 Postman 进行测试:
GET 请求:
选择 GET 方法,输入 URL http://localhost:8080/someGet,点击 Send。
POST 请求:
选择 POST 方法,输入 URL http://localhost:8080/somePost,点击 Send。
PUT 请求:
选择 PUT 方法,输入 URL http://localhost:8080/somePut,点击 Send。
DELETE 请求:
选择 DELETE 方法,输入 URL http://localhost:8080/someDelete,点击 Send。
PATCH 请求:
选择 PATCH 方法,输入 URL http://localhost:8080/somePatch,点击 Send。
HEAD 请求:
选择 HEAD 方法,输入 URL http://localhost:8080/someHead,点击 Send。
OPTIONS 请求:
选择 OPTIONS 方法,输入 URL http://localhost:8080/someOptions,点击 Send。
这里只展示一个:
在这里插入图片描述

相关文章:

Gin框架操作指南08:日志与安全

官方文档地址(中文):https://gin-gonic.com/zh-cn/docs/ 注:本教程采用工作区机制,所以一个项目下载了Gin框架,其余项目就无需重复下载,想了解的读者可阅读第一节:Gin操作指南&#…...

鸿蒙系统 VS 安卓系统,谁将引领未来移动操作系统?

文章目录 1. 系统架构:微内核 vs 宏内核2. 设备生态:单设备 vs 全场景分布式3. 开发生态:安卓主导地位 vs 鸿蒙迅速崛起4. 性能与流畅度:安卓优化 vs 鸿蒙调度优势5. 安全性:Google 主导 vs 微内核高安全6. 市场影响力…...

PyTorch 中 functional.py 文件介绍

PyTorch PyTorch 是一个开源的机器学习库,广泛用于计算机视觉和自然语言处理等应用。它由 Facebook 的人工智能研究团队开发,并得到了许多研究机构和企业的支持。PyTorch 以其易用性、灵活性和强大的社区支持而受到欢迎。一些特点如下: 动态…...

SQL Injection | SQL 注入 —— 报错盲注

关注这个漏洞的其他相关笔记:SQL 注入漏洞 - 学习手册-CSDN博客 0x01:报错盲注 —— 理论篇 报错盲注(Error-Based Blind SQL Injection)是一种常见的 SQL 注入技术,适用于那些页面不会直接显示后端处理结果的查询方式…...

网络通信与并发编程(四)操作系统、进程理论、开启进程的两种方式

多道技术、进程理论 文章目录 多道技术、进程理论一、操作系统1.1操作系统1.2操作系统中的常见概念1.3操作系统的发展史 二、进程理论2.1同步、异步、阻塞、非阻塞2.2 进程的层次结构2.3 运行态、阻塞态、就绪态 三、开启进程的两种方式3.1使用Process创建进程的两种方式3.2 父…...

Java--集合(三)之vectorlinkedlisthashset结构

文章目录 0.架构图1.vector解析2.LinkedList分析2.1源码分析2.2迭代器遍历的三种方式 3.set接口的使用方法3.1基本使用说明3.2基本遍历方式3.3HashSet引入3.4数组链表模拟3.5hashset扩容机制3.6hashset源码解读3.7扩容*转成红黑树机制**我的理解 0.架构图 1.vector解析 和之前介…...

upload-labs Pass-04

upload-labs Pass-04 在进行测试前,先了解一下.htaccess文件 .htaccess文件 .htaccess是Apache网络服务器一个配置文件,当.htaccess文件被放置在一个通过Apache Web服务器加载的目录中,.htaccess文件会被Apache Web服务器软件检测并执行&…...

如何修改jupyter notebook的工作目录

1.生成配置文件: 打开Anaconda Prompt,输入如下命令 jupyter notebook --generate-config 用代码可以找到配置文件位置,如果没有填y可以生成。 2.修改配置文件: 修改jupyter_notebook_config.py的配置文件,需将c.Not…...

23种设计模式具体实现方法

提示:文章 文章目录 前言一、背景二、设计模式1、代理模式2、适配器模式2.1 总结 三、3.1 总结 前言 前期疑问: 本文目标: 一、背景 最近 二、设计模式 1、代理模式 参考的这篇文章,代理模式(Proxy) 同时这篇文章还引用了另…...

cisco网络安全技术第3章测试及考试

测试 使用本地数据库保护设备访问(通过使用 AAA 中央服务器来解决)有什么缺点? 试题 1选择一项: 必须在每个设备上本地配置用户帐户,是一种不可扩展的身份验证解决方案。 请参见图示。AAA 状态消息的哪一部分可帮助…...

数据结构练习题5(链表和栈)

1环形链表 II 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测…...

计算机网络408真题解析(湖科大教书匠)

09年...

uniapp+vue3+uview-plus修改默认样式

最近使用uniappvue3uview-plus开发微信小程序中,使用uview-plus自定义底部导航栏tabbar时,遇到修改默认样式不生效问题 使用传统的 ::v-deep、:deep、::v-deep,或者style标签中去掉scoped也是无效的,有好的方案欢迎交流&#xff…...

数控机械制造工厂ERP适用范围有哪些

在当今制造业高速发展的背景下,企业资源计划(ERP)系统已成为提升工厂管理效率、实现生产自动化与信息化的关键工具。特别是对于数控机械制造工厂而言,一个合适的ERP系统能够帮助其优化生产流程、提高产品质量、降低生产成本并增强市场竞争力。 1. 生产计…...

华为配置 之 Console线路配置

目录 简介: 知识点: 配置Console线路密码 1.密码认证模式 2.AAA认证模式 知识点: 总结: 简介: 使用PC模拟器与路由器相连(与交换机相连原理一样),在关机状态下,使用…...

小米等手机彻底关闭快应用

文章目录 快应用的是非最终措施:撤销快应用隐私协议配套措施:安卓去除开屏广告 无用的操作:载快应用小米手机无用,其他手机可以尝试的操作关闭唤起快应用服务打开防止误触、后台启动其他应用 其他措施:冻结、加密快应用…...

【每日一题】24.10.14 - 24.10.20

10.14 直角三角形1. 题目2. 解题思路3. 代码实现(AC_Code) 10.15 回文判定1. 题目2. 解题思路3. 代码实现(AC_Code) 10.16 二次方程1. 题目2. 解题思路3. 代码实现(AC_Code) 10.17 互质1. 题目2. 解题思路3…...

CMake与Qt4/Qt5的结合使用指南

CMake与Qt4/Qt5的结合使用指南 一、同时使用Qt 4和Qt 5二、Qt构建工具2.1 AUTOMOC2.2 AUTOUIC2.3 AUTORCC 三、<ORIGIN>_autogen目标四、Visual Studio生成器五、Windows上的qtmain.lib六、其他文章推荐 在CMake中&#xff0c;您可以方便地找到并使用Qt 4和Qt 5库。Qt 4库…...

TwinCAT3添加PLC轴,并建立PLC轴与NC轴的链接

右键PLC选项&#xff0c;点击创建新项 在弹出的对话框中&#xff0c;选择PLC Templates&#xff0c;然后选择Standard PLC Project&#xff0c;填写项目名称后点击添加 在PLC项目目录中右键GVLs&#xff0c;选择Add&#xff0c;添加Global Variable List&#xff08;全局变…...

Linux操作系统如何制作U盘启动盘

在麒麟系统中有一款U盘启动器软件&#xff0c;它是用于制作系统启动U盘的工具&#xff0c;方便无光驱的电脑安装操作系统&#xff0c;也可以反复使用一个U盘&#xff0c;避免光盘的浪费。下面对该U盘启动器使用方法做详细讲解。 1.准备需要安装的系统镜像文件。 图 1 2.准备1…...

如何防止SpringBoot中的jar反编译?解决相关报错及踩到的坑

目录 1. 面对的场景 2. 方案 2.1 使用代码混淆 2.2 JAR包加密 3. 项目操作 4. 启动方式 5. 踩到的各种坑 5.1 java -jar xxx-0.0.1-SNAPSHOT.jar 没有主清单属性 5.2 Caused by: java.lang.IllegalArgumentException: Unrecognized option: -pwdfxw-jar 1. 面对的场景…...

Axios 基本使用

Axios 是一个异步请求技术,核心作用就是用来在页面中发送异步请求,并获取对应数据在页面中渲染 页面局部更新技术 Ajax 中文网站:https://www.kancloud.cn/yunye/axios/234845 安装: <script src"https://unpkg.com/axios/dist/axios.min.js"></script&g…...

前端大佬都在用的actionDelegationMiddleware究竟有多香?

作为一个前端开发者,我深知跨组件通信的痛点。今天,我要和大家分享一个让我眼前一亮的工具 - alovajs 的 actionDelegationMiddleware。这个中间件简直就是跨组件通信的得力助手!它让我们可以在任意组件中触发其他组件的请求操作,解决了很多麻烦。用了它之后,我感觉整个项目的架…...

解决k8s集群中安装ks3.4.1开启日志失败问题

问题 安装kubesphere v3.4.1时&#xff0c;开启了日志功能&#xff0c;部署时有三个pod报错了 Failed to pull image “busybox:latest”: rpc error: code Unknown desc failed to pull and unpack image “docker.io/library/busybox:latest”: failed to copy: httpRead…...

Qml-Item的Id生效范围

Qml-Item的Id生效范围 前置声明 本实例在Qt6.5版本中做的验证同一个qml文件中&#xff0c;id是唯一的&#xff0c;即不同有两个相同id 的Item;当前qml文件中声明的id在当前文件中有效&#xff08;即如果其它组件中传入的id&#xff0c;与当前qml文件中id 相同&#xff0c;当前…...

【配色网站分享】

个人比较喜欢收藏一些好看的插画、UI设计图和配色&#xff0c;于是有了此篇&#xff0c;推荐一些配色网站&#xff0c;希望能对自己和大家有些帮助。 1.uiGradients 一个主打渐变风网站&#xff0c;还可以直接复制颜色。 左上角的“show all gradients”可以查看一些预设的渐…...

【记录】Android|安卓平板 猫游戏(四款,peppy cat,含下载教程和链接)

前言 网上大部分直接找到的都是 iPad 的猫游戏&#xff0c;安卓的要查英文才找得到&#xff0c;但质量也都一般&#xff0c;或不知道在哪里下载。 遂自己找。 下载测试时间&#xff1a;2024/10/20 文章目录 前言1 检索2 亲测2.1 ✅⭐⭐⭐⭐⭐Cat Alone 1 and 22.2 &#x1f4…...

微前端架构及其解决方案对比

微前端架构及其解决方案对比 微前端架构是一种通过将大型前端应用拆分为多个独立的、可单独部署的小型应用的设计模式。随着这种模式的流行&#xff0c;诞生了多种微前端实现方案&#xff0c;每个方案都有其独特的特点和适用场景。以下是常见的微前端解决方案及其优缺点对比&a…...

git add操作,文件数量太多卡咋办呢,

git add介绍 Git的add命令是用于将文件或目录添加到暂存区&#xff08;也就是索引库&#xff09;&#xff0c;以便在后续的提交&#xff08;commit&#xff09;操作中一并上传到版本库的。具体来说&#xff0c;git add命令有以下几种常见用法&#xff1a; 添加单个文件&#…...

搭建Golang gRPC环境:protoc、protoc-gen-go 和 protoc-gen-go-grpc 工具安装教程

参考文章&#xff1a; 安装protoc、protoc-gen-go、protoc-gen-go-grpc-CSDN博客 一、简单介绍 本文开发环境&#xff0c;均为 windows 环境&#xff0c;mac 环境其实也类似 ~ ① 编译proto文件&#xff0c;相关插件 简单介绍&#xff1a; protoc 是编译器&#xff0c;用于将…...