關于Gin框架中的Cookie和Session的使用方法
引言
在深入探討Cookie和Session之前,我們需要了解HTTP協(xié)議的無狀態(tài)特性。簡單來說,HTTP是一種無狀態(tài)協(xié)議,即每次請求與響應之間都是獨立的,服務器不會記住之前的狀態(tài)信息。這意味著,當用戶從一個頁面跳轉(zhuǎn)到另一個頁面時,服務器無法自動識別這是同一個用戶的請求。為了實現(xiàn)跨請求的數(shù)據(jù)共享,我們可以使用Cookie和Session。本文將結合實際案例,詳細介紹在Go語言的Gin框架中如何使用Cookie和Session。
一、Cookie的詳細用法
1. Cookie的基本概念
Cookie是一種存儲在客戶端瀏覽器中的鍵值對數(shù)據(jù),用于在客戶端和服務器之間傳遞信息。每次向服務器發(fā)送請求時,瀏覽器都會自動攜帶這些Cookie信息。
2. 設置Cookie
在Gin框架中,可以通過c.SetCookie方法設置Cookie。以下是該方法的主要參數(shù):
- name:Cookie的名稱。
- value:Cookie的值。
- maxAge:Cookie的過期時間(秒)。如果只想設置Cookie的保存路徑而不想設置存活時間,可以在此參數(shù)中傳遞nil。
- path:Cookie的路徑。
- domain:Cookie的域名作用域。本地調(diào)試時配置為localhost,正式上線時配置為域名。
- secure:當此值為true時,Cookie在HTTP中是無效的,僅在HTTPS中有效。
- httpOnly:如果設置了此屬性,則通過程序(如JS腳本)將無法讀取到Cookie信息,防止XSS攻擊。
示例代碼:
package main
import (
"github.com/gin-gonic/gin"
)
func TestHandler(c *gin.Context) {
// 獲取客戶端是否攜帶Cookie 獲取名為"username"的Cookie
// 如果不存在將myCookie設為lucas
mycookie, err := c.Cookie("username")
if err != nil {
mycookie = "lucas"
}
// 給客戶端設置Cookie
// func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)
c.SetCookie("username", mycookie, 60*60, "/", "localhost", false, true)
//響應客戶端字符串
c.String(200, "測試Cookie")
}
func main() {
r := gin.Default() // 創(chuàng)建路由,默認使用Logger()和Recovery()中間件
// func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes
r.GET("/cookie", TestHandler)
r.Run(":8888")
}
可以看到服務端給瀏覽器客戶端設置的cookie

3. 獲取cookie
要獲取客戶端請求中的Cookie,可以使用c.Cookie()方法。以下是一個示例:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func getCookie(c *gin.Context) {
// 獲取名為"username"的Cookie
cookie, err := c.Cookie("username")
if err != nil {
c.String(http.StatusOK, "未找到Cookie")
return
}
c.String(http.StatusOK, "Cookie值:"+cookie)
}
func main() {
r := gin.Default()
r.GET("/getCookie", getCookie)
r.Run(":8080")
}
由于我們設置了一條cookie,username為lucas,所以能獲取到

4. 刪除Cookie
刪除Cookie實際上是通過設置其過期時間為負數(shù)來實現(xiàn)的。
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func deleteCookie(c *gin.Context) {
// 刪除名為"username"的Cookie
//實際上就是設置maxAge為負數(shù)
c.SetCookie("username", "", -1, "/", "localhost", false, true)
c.String(http.StatusOK, "刪除Cookie成功")
}
func main() {
r := gin.Default()
//在請求處,將handlers函數(shù)傳進來
r.GET("/deleteCookie", deleteCookie)
r.Run(":8080")
}
在上面的代碼中,c.SetCookie(“username”, “”, -1, “/”, “localhost”, false, true)方法會將名為"username"的Cookie過期時間設置為過去的時間戳,從而刪除該Cookie。
二、Session的詳細用法
1. Session的基本概念
Session是一種記錄客戶狀態(tài)的機制,與Cookie不同的是,Session數(shù)據(jù)保存在服務器上。當客戶端瀏覽器第一次訪問服務器并發(fā)送請求時,服務器端會創(chuàng)建一個Session對象,生成一個類似于key-value的鍵值對,然后將value保存到服務器,將key(通常是一個Cookie)返回到瀏覽器(客戶端)。瀏覽器下次訪問時會攜帶這個key,服務器通過這個key找到對應的Session數(shù)據(jù)。

2. Session的工作原理
- 1: 我們的請求在默認情況下是無狀態(tài)的,所謂的無狀態(tài)就是指,gin定義一個路由地址,在瀏覽器訪問以后,也就是
發(fā)起一個request,到response的過程,整個過程結束后,并不會在服務器端存儲數(shù)據(jù)。這樣就會造成一個問題,
無法解決各路由請求之間數(shù)據(jù)的共享問題。 - 2:如何解決這個問題呢?其實也就是session
- 3:session是一種服務器端的存儲技術,其實在底層就是一個全局的map[string][any]對象。它可以把一些需要各個
路由間共享的數(shù)據(jù)進行存儲在內(nèi)存中,直到服務器關閉或者超時才會清除。 - 4:有了session,為什么還有有sessionId呢?因為要區(qū)分是那個業(yè)務的數(shù)據(jù),因為底層是map,所以大部分情況下都會
用sessionId作為key. - 5:有了session,為啥還要cookie技術呢,cookie是一種客戶端的存儲技術,在創(chuàng)建session的時候,每次都會把這個
sessionId寫入到客戶端瀏覽器的cookie中,后續(xù)給未來的每個路由請求都攜帶這個sessionId, 到服務端的map種去匹配
對應自己的數(shù)據(jù)信息。 - 6:從而達到數(shù)據(jù)的共享。
3. Sesison的應用場景
第一次登錄,服務器給客戶端頒發(fā)一個唯一的sessionId, 并通過http的響應頭返回。客戶端(瀏覽器)發(fā)現(xiàn)返回的數(shù)據(jù)中有cookie數(shù)據(jù)就把這個cookie數(shù)據(jù)存放到內(nèi)存。下次再發(fā)送http請求時,把內(nèi)存中的cookie數(shù)據(jù)再塞到http請求頭中,一并發(fā)給服務器,服務器在解析請求時,發(fā)現(xiàn)請求頭中有cookie,就開始識別cookie中的sessionId,拿到sessionId,我們就知道這個請求時由哪個客戶端發(fā)送來的了。
4. 在Gin框架中使用Session
Gin框架本身并不內(nèi)置對Session的支持,但可以使用第三方的Session中間件來實現(xiàn)。其中比較常用的是github.com/gin-contrib/sessions。
1. 安裝依賴
首先,需要安裝Session中間件:
go get github.com/gin-contrib/sessions

2. 創(chuàng)建基于內(nèi)存的Session
Session存儲引擎有多種實現(xiàn)方式,如基于內(nèi)存、Redis、MongoDB等。以下是一個基于內(nèi)存的示例:
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/memstore"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 創(chuàng)建基于內(nèi)存的存儲引擎
// func NewStore(keyPairs ...[]byte) Store
store := memstore.NewStore([]byte("secret11111"))
// 設置Session中間件
// func Sessions(name string, store Store) gin.HandlerFunc
r.Use(sessions.Sessions("mysession", store))
r.GET("/", func(c *gin.Context) {
// 初始化Session對象
session := sessions.Default(c)
// 設置Session數(shù)據(jù)
session.Set("username", "zhangsan")
// 保存Session數(shù)據(jù)
session.Save()
c.JSON(200, gin.H{"message": "Session設置成功"})
})
r.GET("/get", func(c *gin.Context) {
// 初始化Session對象
session := sessions.Default(c)
// 獲取Session數(shù)據(jù)
username := session.Get("username")
c.JSON(200, gin.H{"username": username})
})
r.Run(":8080")
}
在上面的代碼中,memstore.NewStore([]byte(“secret11111”))創(chuàng)建了一個基于內(nèi)存的Session存儲引擎,sessions.Sessions(“mysession”, store)設置了Session中間件,其中"mysession"是Session的名稱,也是Cookie的名稱。
當我們訪問首頁,設置session成功

當我們訪問/get,可以獲取session

在控制器中使用Session
在Gin框架的控制器中,可以使用sessions.Default©方法獲取當前的Session對象,然后調(diào)用Set、Get和Save等方法來設置、獲取和保存Session數(shù)據(jù)。
3. 創(chuàng)建基于Redis存儲Session
如果希望將Session數(shù)據(jù)保存在Redis中,可以使用github.com/gin-contrib/sessions/redis包。以下是一個示例:
首先,安裝Redis存儲引擎的包:
go get -u github.com/gin-contrib/sessions/redis
然后,配置Redis存儲引擎:
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/redis"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 創(chuàng)建基于Redis的存儲引擎
// func NewStore(size int, network, address, password string, keyPairs ...[]byte) (Store, error)
// func NewStoreWithDB(size int, network, address, password, DB string, keyPairs ...[]byte) (Store, error) 指定DB
store, _ := redis.NewStoreWithDB(10, "tcp", "10.10.0.100:6379", "123456", "0", []byte("secret"))
// 設置Session中間件
r.Use(sessions.Sessions("mysession", store))
r.GET("/", func(c *gin.Context) {
// 初始化Session對象
session := sessions.Default(c)
// 設置Session數(shù)據(jù)
session.Set("username", "jingtian")
// 保存Session數(shù)據(jù)
session.Save()
c.JSON(200, gin.H{"message": "Session設置成功"})
})
r.GET("/get", func(c *gin.Context) {
// 初始化Session對象
session := sessions.Default(c)
// 獲取Session數(shù)據(jù)
username := session.Get("username")
c.JSON(200, gin.H{"username": username})
})
r.Run(":8080")
}
瀏覽器訪問首頁,session保存成功

登錄redis查看,可以看到session

5. Session的基本操作
在獲取到Session對象后,我們可以對其進行設置、獲取、刪除和清除等操作。需要注意的是,每次對Session進行修改后,都需要調(diào)用session.Save()方法來保存更改。
設置Session:
session.Set("username", "zhangsan")
session.Save()
獲取Session:
username := session.Get("username")
刪除Session中的某個鍵值對:
session.Delete("username")
session.Save()
清除整個Session:
session.Clear() session.Save()
三、注意事項
- Cookie的Secure屬性:當設置為
true時,Cookie僅在HTTPS中有效。在生產(chǎn)環(huán)境中,為了安全起見,建議啟用HTTPS并設置Secure屬性。 - Cookie的HttpOnly屬性:設置為
true時,可以防止通過JS腳本讀取Cookie,增加安全性。 - Session的過期時間:可以通過設置Session存儲引擎的Options來配置過期時間等參數(shù)。
- 跨域問題:在涉及跨域請求時,需要確保服務器正確配置了CORS(跨域資源共享)中間件,并允許攜帶Credentials。
- Gob編解碼器:Gin框架的Session中間件使用Gob作為編解碼器。當存儲復雜類型(如struct、map等)時,需要先注冊這些類型,否則會報錯“gob: type not registered for…”。
四、總結
本文詳細介紹了在Go語言的Gin框架中如何使用Cookie和Session來實現(xiàn)跨請求的數(shù)據(jù)共享。通過合理配置和使用這些機制,我們可以有效地管理客戶端狀態(tài),提高應用程序的可用性和安全性。
以上就是關于Gin框架中的Cookie和Session的使用方法的詳細內(nèi)容,更多關于Gin框架Cookie和Session的使用的資料請關注腳本之家其它相關文章!
相關文章
go?tool?pprof?參數(shù)?'-base'?和?'-diff_base&
這篇文章主要介紹了go?tool?pprof?參數(shù)?'-base'?和?'-diff_base'之間的區(qū)別,兩個參數(shù)都是用于計算當前?profile文件減去基準profile文件所獲得的差值,用這個差值生成一個新的profile文件,本文給大家介紹的非常詳細,需要的朋友可以參考下2023-05-05

