当前位置: 首页 > 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…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...