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

在這里插入圖片描述

本文目錄

  • 一、模版渲染
  • 二、自定義模版函數
  • 三、cookie
  • 四、Session
  • 五、cookie、session區別
  • 六、會話攻擊

一、模版渲染

在 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

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名字讀取cookie值data, err := c.Cookie("site_cookie")if err != nil {// 直接返回cookie值c.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,從服務器端的存儲中找到對應的會話數據,從而恢復用戶的會話狀態。

五、cookie、session區別

由于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.pswp.cn/news/896056.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896056.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896056.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【AI繪畫】大衛? 霍克尼風格——自然的魔法(一丹一世界)

大衛? 霍克尼&#xff0c;很喜歡這個老頭&#xff0c;“藝術是一場戰斗”。老先生零九年有了iphone&#xff0c;開始用iphone畫畫&#xff0c;一零年開始用ipad畫畫&#xff0c;用指頭劃拉&#xff0c;據說五分鐘就能畫一幅&#xff0c;每天早上隨手畫幾幅送給身邊的朋友。很c…

解碼 NLP:從萌芽到蓬勃的技術蛻變之旅

內容概況&#xff1a; 主要講述NLP專欄的內容和NLP的發展及其在現代生活中的廣泛應用。專欄強調實踐為主、理論為輔的學習方法&#xff0c;并通過多個生活場景展示了NLP技術的實際應用&#xff0c;如對話機器人、搜索引擎、翻譯軟件、電商推薦和智能客服等。 這邊我就不多做自我…

解決DeepSeek服務器繁忙問題的實用指南

目錄 簡述 1. 關于服務器繁忙 1.1 服務器負載與資源限制 1.2 會話管理與連接機制 1.3 客戶端配置與網絡問題 2. 關于DeepSeek服務的備用選項 2.1 納米AI搜索 2.2 硅基流動 2.3 秘塔AI搜索 2.4 字節跳動火山引擎 2.5 百度云千帆 2.6 英偉達NIM 2.7 Groq 2.8 Firew…

前端(AJAX)學習筆記(CLASS 2):圖書管理案例以及圖片上傳

* BootStrap彈框 功能&#xff1a;不離開當前頁面&#xff0c;顯示單獨內容&#xff0c;供用戶操作 步驟&#xff1a; 1、引入bootstrap.css和bootstrap.js 2、準備彈框標簽&#xff0c;確認結構 3、通過自定義屬性&#xff0c;控制彈框的顯示和隱藏 其中的bootstrap.css…

數據結構:雙鏈表list

list 是 C 標準庫中的雙向鏈表容器。 list初始化示例&#xff1a; #include <list>int n 7;std::list<int> lst; // 初始化一個空的雙向鏈表 lststd::list<int> lst(n); // 初始化一個大小為 n 的鏈表 lst&#xff0c;鏈表中的值默認都為 0std::list<i…

AI Agent Service Toolkit:一站式大模型智能體開發套件

項目簡介 該工具包基于LangGraph、FastAPI和Streamlit構建,提供了構建和運行大模型Agent的最小原子能力,包含LangGraph代理、FastAPI服務、用于與服務交互的客戶端以及一個使用客戶端提供聊天界面的Streamlit應用。用戶可以利用該工具包提供的模板快速搭建基于LangGraph框架…

論文概覽 |《Urban Analytics and City Science》2023.10 Vol.50 Issue.8

本次給大家整理的是《Environment and Planning B: Urban Analytics and City Science》雜志2023年10月第50卷第8期的論文的題目和摘要&#xff0c;一共包括21篇SCI論文&#xff01; 論文1 Advances in geospatial approaches to transport networks and sustainable mobility …

大語言模型推理能力從何而來?

前言 DeepSeek R1采用強化學習進行后訓練&#xff0c;通過獎勵機制和規則引導模型生成結構化思維鏈&#xff08;CoT&#xff09;&#xff0c;從而顯著提升了推理能力。這一創新方法使得DeepSeek R1能夠在無需大量監督數據的情況下&#xff0c;通過自我進化發展出強大的推理能力…

用 WOW.js 和 animate.css 實現動畫效果

用 wow.js 就可以實現動畫效果&#xff0c;但由于里面的動畫樣式太少&#xff0c;一般還會引入 animated.css 第一步&#xff1a;下載 選擇合適的包管理器下載對應的內容 pnpm i wow.js animated.css --save 第二步&#xff1a;引入 在main.js中加入&#xff1a; import …

設計模式教程:解釋器模式(Interpreter Pattern)

1. 什么是解釋器模式&#xff1f; 解釋器模式&#xff08;Interpreter Pattern&#xff09;是一種行為型設計模式&#xff0c;通常用于處理語言&#xff08;例如數學表達式、SQL查詢等&#xff09;中的語法和解釋。該模式定義了一個文法&#xff0c;并通過解釋器類來解釋文法中…

STM32MP157A單片機移植Linux驅動深入版

需求整理 在Linux設備樹中新增leds節點&#xff0c;其有3個gpio屬性&#xff0c;分別表示PE10對應led1&#xff0c;PF10對應led2&#xff0c;PE8對應led3&#xff0c;設備樹鍵值對如下&#xff1a; leds { led1-gpio <&gpioe 10 0>; led2-gpio &l…

本地DeepSeek模型GGUF文件轉換為PyTorch格式

接前文,我們在本地Windows系統上,基于GGUF文件部署了DeepSeek模型(DeepSeek-R1-Distill-Qwen-1.5B.gguf版本),但是GGUF是已經量化的版本,我們除了對其進行微調之外,無法對其訓練,那么還有沒有其他辦法對本地的GGUF部署的DeepSeek模型進行訓練呢?今天我們就反其道而行之…

http代理IP怎么實現?如何解決代理IP訪問不了問題?

HTTP代理是一種網絡服務&#xff0c;它充當客戶端和目標服務器之間的中介。當客戶端發送請求時&#xff0c;請求首先發送到代理服務器&#xff0c;然后由代理服務器轉發到目標服務器。同樣&#xff0c;目標服務器的響應也會先發送到代理服務器&#xff0c;再由代理服務器返回給…

人工智能之數學基礎:施密特正交化

本文重點 在前面的課程中,我們學習了線性空間的基,其中有一個標準正交基的概念,假設現在有一個線性向量空間,然后已經確定了該線性空間的一組基,那么如何將其轉變為標準正交基。本文將學習如何通過施密特正交化完成這個任務。 施密特正交化 施密特正交化(Schmidt Orth…

Spark(2)linux和簡單命令

&#xff08;一&#xff09;Linux的文件系統 文件系統&#xff1a;操作系統中負責管理和存儲文件信息的軟件結構稱為文件管理系統。 文件系統的結構通常叫做目錄樹結構&#xff0c;從斜桿/根目錄開始; Linux號稱萬物皆文件&#xff0c;意味著針對Linux的操作&#xff0c;大多…

Grok 3.0 Beta 版大語言模型評測

2025年2月17日至18日&#xff0c;全球首富埃隆馬斯克&#xff08;Elon Musk&#xff09;攜手其人工智能公司xAI&#xff0c;在美國重磅發布了Grok 3.0 Beta版。這款被譽為“迄今為止世界上最智能的語言模型”的AI&#xff0c;不僅集成了先進的“DeepSearch”搜索功能&#xff0…

基于COSTAR模型的內容創作:如何用框架提升寫作質量

目錄 前言1. Context&#xff08;上下文&#xff09;&#xff1a;理解背景&#xff0c;奠定寫作基礎1.1 何為上下文1.2 上下文的作用1.3 案例解析 2. Objective&#xff08;目標&#xff09;&#xff1a;明確寫作方向&#xff0c;避免跑題2.1 確立目標2.2 如何設定目標2.3 案例…

Springboot應用開發工具類整理

目錄 一、編寫目的 二、映射工具類 2.1 依賴 2.2 代碼 三、日期格式 3.1 依賴 3.2 代碼 四、加密 4.1 代碼 五、Http請求 5.1 依賴 5.2 代碼 六、金額 6.1?代碼 七、二維碼 7.1 依賴 7.2 代碼 八、坐標轉換 8.1 代碼 九、樹結構 9.1?代碼 9.1.1 節點 …

【Research Proposal】基于提示詞方法的智能體工具調用研究——研究問題

博客主頁&#xff1a; [小????????] 本文專欄: AIGC | ChatGPT 文章目錄 &#x1f4af;前言&#x1f4af;研究問題1. 如何優化提示詞方法以提高智能體的工具調用能力&#xff1f;2. 如何解決提示詞方法在多模態任務中的挑戰&#xff1f;3. 如何通過提示詞優化智能體…

Java 大視界 -- 國際競爭與合作:Java 大數據在全球市場的機遇與挑戰(94)

&#x1f496;親愛的朋友們&#xff0c;熱烈歡迎來到 青云交的博客&#xff01;能與諸位在此相逢&#xff0c;我倍感榮幸。在這飛速更迭的時代&#xff0c;我們都渴望一方心靈凈土&#xff0c;而 我的博客 正是這樣溫暖的所在。這里為你呈上趣味與實用兼具的知識&#xff0c;也…