Gin 中單一Cookie的應用
1 )路由處理
package routers
import (
"gin-demo/controllers/web"
"github.com/gin-gonic/gin"
)
func WebRoutersInit(r *gin.Engine) {
webRouters := r.Group("/")
{
webRouters.GET("/", web.WebCtrl{}.Index)
webRouters.GET("/setcookie", web.WebCtrl{}.SetCookie)
webRouters.GET("/getcookie", web.WebCtrl{}.GetCookie)
webRouters.GET("/delcookie", web.WebCtrl{}.DelCookie)
}
}
2 ) 控制器處理
package web
import (
"net/http"
"github.com/gin-gonic/gin"
)
type WebCtrl struct{}
// 設置 cookie
func (con WebCtrl) SetCookie(c *gin.Context) {
// 設置 cookie
// 第一個
c.SetCookie("username", "張三", 3600, "/", "localhost", false, true)
// 第二個
c.SetCookie("hobby", "吃飯 睡覺", 5, "/", "localhost", false, true)
// 響應
c.String(http.StatusOK, "set cookie")
}
// 獲取 cookie
func (con WebCtrl) GetCookie(c *gin.Context) {
// 獲取 cookie
username, _ := c.Cookie("username")
hobby, _ := c.Cookie("hobby")
// 響應
c.String(http.StatusOK, "username=%v----hobby=%v", username, hobby)
}
// 刪除 cookie
func (con WebCtrl) DelCookie(c *gin.Context) {
// 刪除 cookie
c.SetCookie("username", "張三", -1, "/", "localhost", false, true) // 刪除一個
// 響應
c.String(http.StatusOK, "delete cookie")
}
-
設置cookie時,設置了兩個不同過期時間的cookie
-
5s 后第一個cookie 自動丟失
-
訪問 /delcookie 路由,第二個路由被主動刪除
-
HTTP 是無狀態(tài)協議,當你瀏覽了一個頁面
-
然后轉到同一個網站的另一個頁面,服務器無法認識到這是同一個瀏覽器在訪問同一個網站
-
每一次的訪問,都是沒有任何關系的
-
如果我們要實現多個頁面之間共享數據的話
-
我們就可以使用 Cookie 或者 Session 實現
-
cookie 是存儲于訪問者計算機的瀏覽器中
-
可以讓我們用同一個瀏覽器訪問同一個域名的時候共享數據
-
所以,cookie的功能
- 保持用戶登錄狀態(tài)
- 保存用戶瀏覽的歷史記錄
- 猜你喜歡,智能推薦
- 電商網站的加入購物車
-
cookie的文檔
- https://gin-gonic.com/zh-cn/docs/examples/cookie/
-
設置cookie時的API
c.SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)
- 第一個參數 key
- 第二個參數 value
- 第三個參數 過期時間
- 如果只想設置 Cookie 的保存路徑而不想設置存活時間
- 可以在第三個參數中傳遞 nil
- 第四個參數 cookie 的路徑
- 第五個參數 cookie 的路徑 Domain 作用域
- 本地調試配置成 localhost , 正式上線配置成域名
- 第六個參數是 secure
- 當 secure 值為 true 時,cookie 在 HTTP 中是無效,在 HTTPS 中才有效
- 第七個參數 httpOnly
- 是微軟對 COOKIE 做的擴展, 如果在 COOKIE 中設置了“httpOnly”屬性
- 則通過程序(JS 腳本、applet 等)將無法讀取到 COOKIE 信息,防止 XSS 攻擊產生
多級域名共享 cookie
- 不管二級或多級域名,可以設置根域名來共享數據
- 分別把 a.xyz.com 和 b.xyz.com, 以及 c.b.xyz.com 解析到我們的服務器
- 我們想的是用戶在 a.xyz.com 中設置 Cookie 信息后
- 在 b.xyz.com 以及 c.b.xyz.com 中獲取剛才設置的cookie
- 也就是實現多個二級域名共享 cookie,這時候就可以這樣設置 cookie
c.SetCookie("usrename", "張三", 3600, "/", ".xyz.com", false, true)
單體架構 基于 cookie 存儲 session
概述
1 ) 單單使用 cookie 的限制
- 單單基于 cookie 的設定,只能讀取單個客戶端中的數據,不能做到數據在服務端共享
- 服務端Cookie技術是將數據存儲在用戶的瀏覽器上,每次瀏覽器發(fā)送請求時
- 都會攜帶這些Cookie數據發(fā)送到服務器。Cookie的大小通常受到限制
- 大多數瀏覽器對單個Cookie的大小有4096字節(jié)的限制
- 盡管現在一些新的瀏覽器和客戶端設備支持更大的Cookie
- 此外,用戶可以選擇禁用Cookie功能,這會影響Cookie的正常使用
2 )基于 cookie 的 session 技術
- 與Cookie不同,Session技術將數據存儲在服務器上
- 這意味著Session沒有存儲大小的限制,只受限于服務器的內存大小
- Session在用戶訪問期間一直存在在服務器上,直到會話結束或服務器決定刪除它
- 由于Session存儲在服務器上,因此相比Cookie,它更安全,不容易被篡改
- 但是,如果服務器上有大量的Session,會占用較多的服務器資源
- 可能會影響服務器的性能
示例
1 )主程序配置 在 main.go 中
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
func main() {
// 創(chuàng)建一個默認的路由引擎
r := gin.Default()
// ... 跳過其他
// 在路由配置之上,配置session中間件
cookieSessionSecret := "sdfdssdsfs_s?d2sdfsf@^s_" // 是用于加密的密鑰
// 創(chuàng)建基于 cookie 的存儲引擎
store := cookie.NewStore([]byte(cookieSessionSecret))
// 配置session的中間件 store是前面創(chuàng)建的存儲引擎,我們可以替換成其他存儲引擎
r.Use(sessions.Sessions("xxproject_session", store))
// ... 跳過其他
}
2 ) 路由配置
package routers
import (
"gin-demo/controllers/web"
"github.com/gin-gonic/gin"
)
func WebRoutersInit(r *gin.Engine) {
webRouters := r.Group("/")
{
webRouters.GET("/", web.WebCtrl{}.Index)
webRouters.GET("/setsession", web.WebCtrl{}.SetSession)
webRouters.GET("/getsession", web.WebCtrl{}.GetSession)
webRouters.GET("/delsession", web.WebCtrl{}.DelSession)
}
}
3 ) controller 控制器
package web
import (
"net/http"
"github.com/gin-contrib/sessions" // 則個是用于 直接獲取 cookie 內容的
"github.com/gin-gonic/gin"
)
type WebCtrl struct{}
// 設置 session
func (con WebCtrl) SetSession(c *gin.Context) {
session := sessions.Default(c)
// 配置session的過期時間
session.Options(sessions.Options{
// MaxAge: 3600 * 6, // 6hrs MaxAge單位是秒
MaxAge: 5, // 5 s 過期
})
session.Set("username", "張三 111")
session.Save() // 設置session的時候必須調用
// 響應
c.String(http.StatusOK, "set session: %v", session.Get("username"))
}
// 獲取 session
func (con WebCtrl) GetSession(c *gin.Context) {
session := sessions.Default(c)
username := session.Get("username")
// 響應
c.String(http.StatusOK, "get session username=%v", username)
}
// 刪除 session
func (con WebCtrl) DelSession(c *gin.Context) {
session := sessions.Default(c)
session.Delete("username")
session.Save() // 這將從 Cookie中 中刪除 session 數據
username := session.Get("username") // 獲取 session username
// 響應
c.String(http.StatusOK, "delete session %v", username)
}
- 基于cookie的 session 技術如上是基本使用程序
- 需要注意的是,關于 session 刪除同步到 cookie 刪除是自動設置的
- 調用 session 的 Delete 和 Save 方法來更新 Cookie
- 由于 session 數據已經被刪除,這個操作會創(chuàng)建一個新的、空的 Cookie
- 這實際上會導致瀏覽器端的舊 Cookie 過期并被刪除,所以無需我們控制cookie
分布式架構下 基于 redis 存儲 session
概述
- 如果項目部署在多臺機器上,單體架構下的session無法共享,需要借助第三方來同步數據
- 這時候就會用到 redis 或其他服務器存儲技術,在負載均衡下的多臺機器共享數據的場景
- 就是分布式架構下的 session 應用場景
示例
1 )主程序 main.go
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/redis"
"github.com/gin-gonic/gin"
)
func main() {
// 創(chuàng)建一個默認的路由引擎
r := gin.Default()
// ... 跳過其他
// 在路由配置之上,配置session中間件
redisSessionSecret := "sdfdssdsfs_s?d2sdfsf@^s_" // 是用于加密的密鑰
// 配置session中間件
store, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []byte(redisSessionSecret))
r.Use(sessions.Sessions("mysession", store))
// ... 跳過其他
}
2 ) 路由和控制器同上面的 cookie based session 示例,這里不再贅述文章來源:http://www.zghlxwxcb.cn/news/detail-835651.html
3 )注意文章來源地址http://www.zghlxwxcb.cn/news/detail-835651.html
- 初始化基于 redis 的session存儲引擎, 參數說明:
- 第 1 個參數 - redis 最大的空閑連接數
- 第 2 個參數 - 數通信協議 tcp 或者 udp
- 第 3 個參數 - redis 地址, 格式,host:port
- 第 4 個參數 - redis 密碼
- 第 5 個參數 - session 加密密鑰
- 同步刪除 session 的時候,redis 的數據也會被同步刪除,同時瀏覽器的Cookie數據也會同步消失
- 有時候需要手動刪除,比如客戶端調用退出登錄接口的時候,手動調用 session的刪除和保存方法
其他
- 關于多 session 和 其他存儲引擎的 session 都在文檔中
- 參考:https://github.com/gin-contrib/sessions
到了這里,關于Gin框架: Cookie和Session在單體架構和分布式架構下的應用的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!