【Gin】2:快速上手Gin框架(模版、cookie、session)

ops/2025/2/22 18:26:49/

在这里插入图片描述

本文目录

  • 一、模版渲染
  • 二、自定义模版函数
  • 三、cookie
  • 四、Session
  • 五、cookiesession区别
  • 六、会话攻击

一、模版渲染

Gin 框架中,模板主要用于动态生成 HTML 页面,结合 Go 语言的模板引擎功能,实现数据与视图的分离。

模板渲染是一种动态生成 HTML 页面的技术,通过模板文件和动态数据的结合,Web 应用可以为每个用户生成不同的内容。Gin 使用 Go 标准库 html/template 提供模板功能,该模板引擎基于 HTML,能够避免常见的跨站脚本攻击 (XSS)。

创建一个template模版文件,其中body中的.title就是动态的数据,需要后端请求后显示。

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>gin_templates</title>
</head>
<body>
{{.title}}
</body>
</html>

写一个简单的请求demo来看看模版返回。

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()// 模板解析r.LoadHTMLFiles("./templates/index.tmpl")r.GET("/index", func(ctx *gin.Context) {// 模板的渲染ctx.HTML(http.StatusOK, "index.tmpl", gin.H{"title": "hello,我是模板",})})r.Run(":9090") // 启动server
}

通过Post请求工具可以看到已经正确加载了模版内容。

在这里插入图片描述
如果有多个模版,可以统一进行对应的渲染:

	r.LoadHTMLGlob("templates/**")

如果目录为templates/post/index.tmpltemplates/user/index.tmpl这种,可以

	// **/* 代表所有子目录下的所有文件router.LoadHTMLGlob("templates/**/*")

二、自定义模版函数

那么是否可以实现下面的效果呢,答案是可以的,通过自定义模版函数进行处理即可。

在这里插入图片描述
在模板渲染中,默认情况下,Go 的模板引擎会对所有输出的内容进行 HTML 转义,以防止跨站脚本攻击(XSS)。例如,如果模板中输出的内容是

Hello
,模板引擎会将其渲染为 <div>Hello</div>,这样浏览器会将其视为普通文本,而不是 HTML 标签。

当我们把代码改为下面时,会发现进行了HTML转义,并不是我们想要的状态。

	r.GET("/index", func(c *gin.Context) {// HTML请求// 模板的渲染c.HTML(http.StatusOK, "index.tmpl", gin.H{"title": "<a href='http://baidu.com'>跳转到其他地方</a>",})})

在这里插入图片描述

在这里插入图片描述
所以现在我们可以添加一个函数,让这个模版原样输出,不再进行html转义了。(放在加载模版之前即可),并且将index中的代码改为如下:{{.title | safe }}

	r.SetFuncMap(template.FuncMap{"safe": func(str string) template.HTML {return template.HTML(str)},})

cookie_101">三、cookie

http是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分两次请求是否由同一个客户端发出。

Cookie就是解决HTTP协议无状态的方案之一。

实际上就是服务器保存在浏览器上的一段信息,浏览器有了Cookie之后,每次向服务器发送请求时都会将信息发送刚给服务器,服务器就可以根据该信息处理请求。

Cookie由服务器创建,发送给浏览器,浏览器保存。

cookie的函数签名如下:

func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)
参数名类型说明
namestringcookie名字
valuestringcookie
maxAgeint有效时间,单位是秒,MaxAge=0 忽略MaxAge属性,MaxAge<0 相当于删除cookie, 通常可以设置-1代表删除,MaxAge>0 多少秒后cookie失效
pathstringcookie路径
domainstringcookie作用域
secureboolSecure=true,那么这个cookie只能用https协议发送给服务器
httpOnlybool设置HttpOnly=true的cookie不能被js获取到
	r.GET("/cookie", func(c *gin.Context) {// 设置cookiec.SetCookie("site_cookie", "cookievalue", 3600, "/", "localhost", false, true)})

通过post工具可以查到对应的cookie
在这里插入图片描述
通过浏览器进入开发者模式也可以查看到对应的cookie

在这里插入图片描述
也可以进行cookie读取,通过下面代码。

func main() {r := gin.Default()r.GET("/read", func(c *gin.Context) {// 根据cookie名字读取cookiedata, err := c.Cookie("site_cookie")if err != nil {// 直接返回cookiec.String(200, "not found!")return}c.String(200, data)})r.Run(":9090") // 启动server
}

在这里插入图片描述
删除cookie比较简单,通过将将cookie的MaxAge设置为-1, 达到删除cookie的目的。

r.GET("/del", func(c *gin.Context) {// 设置cookie  MaxAge设置为-1,表示删除cookiec.SetCookie("site_cookie", "cookievalue", -1, "/", "localhost", false, true)c.String(200,"删除cookie")})

四、Session

会话(Session) 是一种用于在 Web 应用中跟踪用户状态的技术。它允许服务器在多个 HTTP 请求之间保持用户的状态信息,从而实现诸如用户登录、购物车等功能。

当用户第一次访问 Web 应用时,服务器会创建一个唯一的会话标识符(Session ID),并将其存储在服务器端的会话存储中。

Gin框架中,可以依赖gin-contrib/sessions中间件处理session

引入session的依赖。

 go install github.com/gin-contrib/sessions@latest
package mainimport ("fmt""github.com/gin-contrib/sessions""github.com/gin-contrib/sessions/cookie""github.com/gin-gonic/gin"
)func main() {r := gin.Default()// 创建基于cookie的存储引擎,secret 参数是用于加密的密钥,用于对存储在 Cookie 中的会话数据进行加密store := cookie.NewStore([]byte("secret"))// sessions.Sessions:注册会话中间件。这个中间件会自动处理会话的创建、读取和更新,并将会话数据存储在客户端的 Cookie 中。// 设置session中间件,参数mysession,指的是session的名字,也是cookie的名字// store是前面创建的存储引擎,我们可以替换成其他存储引擎r.Use(sessions.Sessions("mysession", store))r.GET("/hello", func(c *gin.Context) {// 初始化session对象session := sessions.Default(c)// 通过session.Get读取session// session是键值对格式数据,因此需要通过key查询数据if session.Get("hello") != "world" {fmt.Println("没读到")// 设置session数据session.Set("hello", "world")session.Save()}c.JSON(200, gin.H{"hello": session.Get("hello")})})r.Run(":8080")
}

在这里插入图片描述
通过上面代码,我们可以验证session。这里我们是使用cookie进行存储的,也可以通过redis进行存储。

通过cookie进行存储的session是这样的:当用户第一次访问服务器时,服务器会为用户创建一个唯一的会话标识符(Session ID),并将与该会话相关的数据存储在服务器端(如内存、数据库或文件系统中)。

服务器将 Session ID 发送给客户端(通常是通过设置一个 Cookie)。客户端(浏览器)会在后续的请求中自动将这个 Cookie(包含 Session ID)发送回服务器。

服务器通过客户端发送的 Session ID,从服务器端的存储中找到对应的会话数据,从而恢复用户的会话状态。

cookiesession_239">五、cookiesession区别

由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie 的工作原理。

Cookie是存储在客户端(用户浏览器)的小块数据,可以用来记住用户的相关信息,例如登录凭证或偏好设置。它们随每个HTTP请求发送给服务器,并且可以被服务器读取以维持会话或个性化用户体验。

再比如想象用户登录银行网站。服务器创建一个包含会话标识符的Cookie,并通过Set-Cookie头部发送回用户的浏览器。浏览器存储此Cookie,并在随后的请求中将其发送回服务器,允许服务器识别用户并在多个页面加载中保持他们的登录状态。

若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。

若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在浏览器的不同进程间共享。这种称为持久Cookie。


客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。每个用户访问服务器都会建立一个session并自动分配一个SessionId,用于标识用户的唯一身份。

也就是会话用于跟踪用户在多个页面请求期间的状态。它们通常存储在服务器端,并且与唯一的会话标识符(通常是会话ID)相关联,会话ID作为Cookie发送给客户端。会话允许服务器在用户访问期间记住有关用户的信息。

用户在电子商务网站上购物。服务器为用户创建一个会话,存储他们的购物车项目和其他相关信息。会话ID作为Cookie发送给用户的浏览器。随着用户在网站上导航,Cookie中的会话ID允许服务器访问用户会话数据,使用户能够无缝购物体验。

服务器通过SessionId作为key,读写对应的value,这就达到了保持会话信息的目的。


所以,为什么有了cookie还要有session

  • 存储位置和安全性

cookie 数据存储在客户端(用户的浏览器中)。由于 Cookie 数据存储在客户端,用户可以轻松查看和修改 Cookie 内容。即使通过加密和签名增强安全性,也无法完全防止用户篡改。Cookie 的大小有限制,通常不超过 4KB,且浏览器对每个域名的 Cookie 数量也有限制。

Session 数据存储在服务器端,客户端只保存一个 Session ID(通常通过 Cookie 传递)。由于数据存储在服务器端,用户无法直接访问或修改 Session 数据,安全性更高。服务器端的存储容量通常比客户端大得多,可以存储更复杂的数据结构。

  • 数据隐私和敏感信息

Cookie 数据存储在客户端,即使是加密的,也存在被窃取或篡改的风险。因此,不适合存储敏感信息(如密码、用户身份信息等)。Session 数据存储在服务器端,可以安全地存储敏感信息。例如,用户登录后,服务器可以将用户的认证状态和权限信息存储在 Session 中,而无需暴露给客户端。

  • 分布式和可扩展性

Cookie 数据存储在客户端,不依赖于服务器的存储。但如果需要在多个服务器之间共享会话数据(如分布式应用),Cookie 无法直接实现。

Session 数据存储在服务器端,可以通过多种方式实现分布式存储(如 Redis、数据库等),从而支持分布式应用和负载均衡。在分布式环境中,Session ID 可以通过 Cookie 传递给客户端,而实际的会话数据存储在共享的存储系统中,从而实现会话的共享和同步。

Session 数据存储在服务器端,客户端只需要发送一个轻量级的 Session ID(通常是一个短字符串),从而减轻客户端的负担,提高性能。

六、会话攻击

如果客户端存储的 SessionID 被劫持,攻击者确实可能通过获取 SessionID 冒充用户身份,从而对服务器进行非法操作。然而,虽然无法完全杜绝 SessionID 被窃取的风险,但可以通过多种防御措施来降低这种风险,并防止攻击者利用窃取的 SessionID 进行有效攻击。

  • 使用 HTTPS 协议

通过 HTTPS 加密客户端与服务器之间的通信,可以防止 SessionID 在传输过程中被中间人攻击窃取。

  • 设置 Cookie 的 HttpOnly 和 Secure 属性

HttpOnly:设置 HttpOnly 属性后,Cookie 无法被客户端脚本(如 JavaScript)访问,从而防止通过 XSS 攻击窃取 SessionID。

Secure:设置 Secure 属性后,Cookie 只会在 HTTPS 协议下传输,进一步防止 SessionID 被窃取。

  • 定期更新 SessionID

在用户登录、权限变更或定期时间间隔内更新 SessionID,可以减少攻击者利用旧 SessionID 的机会。同时通过检测客户端的 User-Agent、IP 地址或其他标识信息是否发生变化,可以判断是否为合法用户。如果检测到异常,可以要求用户重新登录。


http://www.ppmy.cn/ops/160567.html

相关文章

去中心化的共同运营平台 方案

实现一个 去中心化的共同运营平台 需要结合技术架构、治理模式和经济模型的设计&#xff0c;同时解决信息真实性、用户激励和去中心化治理的挑战。以下是实现这一目标的路径和关键要素&#xff1a; 一、技术架构设计 1. 去中心化存储与数据管理 区块链底层&#xff1a;使用区…

react(9)-redux

使用CRA快速创建react项目 npx create-react-app react-redux 安装配套工具 npm i reduxjs/toolkit react-redux 启动项目 在创建项目时候会出现一个问题 You are running create-react-app 5.0.0, which is behind the latest release (5.0.1). We no longer support…

从零到一:构建现代 React 应用的完整指南

1. create-react-app (CRA) 简介: create-react-app 是官方推荐的 React 项目脚手架工具,提供了一个开箱即用的开发环境,帮助开发者快速启动 React 应用。它会自动配置 Webpack、Babel、ESLint 等工具,让你专注于开发而不需要手动配置工具链。 特点: 零配置:CRA 自动配…

Apache Spark 的主要特点

Apache Spark 是一个大数据处理框架&#xff0c;提供了快速、通用的数据处理引擎&#xff0c;支持在大规模数据集上进行高效的并行处理。它通过基于内存的计算以及优化的调度来加速数据处理任务&#xff0c;比传统的基于磁盘的数据处理框架&#xff08;如Hadoop&#xff09;要快…

Django-Vue 学习-VUE

主组件中有多个Vue组件 是指在Vue.js框架中&#xff0c;主组件是一个父组件&#xff0c;它包含了多个子组件&#xff08;Vue组件&#xff09;。这种组件嵌套的方式可以用于构建复杂的前端应用程序&#xff0c;通过拆分功能和视图&#xff0c;使代码更加模块化、可复用和易于维…

Python 将PPT幻灯片和形状转换为多种图片格式(JPG, PNG, BMP, SVG, TIFF)

目录 安装所需的库 使用Python将PowerPoint幻灯片转换为JPG、PNG和BMP图片 按实际尺寸将幻灯片保存为图片 按自定义尺寸将幻灯片保存为图片 使用Python将PowerPoint幻灯片转换为SVG图片 使用Python将PowerPoint幻灯片转换为多页TIFF图片 使用Python将PowerPoint幻灯片中…

oracle apex post接口

日常记录 使用到了apex_json方式接收 、、、1 首先&#xff0c;接口通过body传递过来&#xff0c;成功接收到&#xff0c; 数据格式为 JSON_OBJECT_T l_json : JSON_OBJECT_T.parse(:body); 这里我用参数接收到 然后 里面是包含了 "data" 我用 继续接收到这个 l…

MATLAB基础学习相关知识

MATLAB安装参考&#xff1a;抖音-记录美好生活 MATLAB基础知识学习参考&#xff1a;【1小时Matlab速成教程-哔哩哔哩】 https://b23.tv/CnvHtO3 第1部分&#xff1a;变量定义和基本运算 生成矩阵&#xff1a; % 生成矩阵% 直接法% ,表示行 ;表示列 a [1,2,3;4,5,6;7,8,9];%…