<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      一文了解Gin對Cookie的支持

      1. 引言

      本文將從Web應用程序處理請求時需要用戶信息,同時HTTP又是無狀態協議這個矛盾點出發。從該問題出發,簡單描述了解決該問題的Token 機制,進而引出Cookie的實現方案。

      基于此我們將詳細描述Cookie的規范,然后詳細描述具體的實現方式,進一步描述Gin 框架對Cookie 操作提供的API,最終提供了一個詳細的代碼實現。

      我們還將詳細描述Gin 框架提供API 的實現原理,幫助用戶更好得使用這兩個API

      2. 問題引入

      如何使用Gin搭建一個Go Web應用程序 一文中,我們已經了解了如何使用Gin 搭建一個簡單的Web應用程序。然而,在現實的Web應用程序中,大部分功能都是需要用戶的身份信息才能處理。舉例來說,在一個視頻網站查看用戶最近觀看記錄,如果缺少用戶身份信息,此時將無法對請求進行處理。

      但是HTTP協議的設計,是無狀態的,也就是每次請求都是獨立的。基于此,應該有一套機制,能夠在用戶身份認證成功后,給用戶分配一個Token,后續用戶在每次請求時,都攜帶上該Token,使得服務器能夠從請求中獲取用戶信息,解決HTTP無狀態問題。大概流程如下:

      上面流程中,需要服務端按照某個協議,向客戶端返回Token;客戶端通過該協議,成功解析出服務端返回的Token,然后在每次請求中攜帶該Token。然后服務器端再根據協議,從中解析出Token 信息,獲取請求用戶信息。

      當前常用的有CookieJwtOAuth2.0 等標準,其各有優缺點。其中Cookie 是一種存儲在客戶端瀏覽器中的數據。服務端可以通過設置HTTP響應頭將Token 存儲在Cookie當中,并在后續請求中從Cookie 中讀取Token。而JWT 則是一種基于JSON格式的安全令牌,可用于在客戶端和服務端之間傳遞信息。

      之前,我們在 一文讀懂Cookie 中,已經了解Cookie的相關內容。基于此,我們這次使用Cookie 來實現上述所說的流程,按照Cookie的規范來實現Token的返回和請求中Token 的解析。

      3. 實現

      3.1 Cookie規范說明

      這里我們對HTTP協議中的Cookie 規范再補充一下,這里分為兩部分,第一部分是服務端如何向客戶端發送 Cookie ,第二部分是客戶端向服務端發送請求時如何攜帶Cookie 信息。

      對于服務端向客戶端發送Cookie的手段,HTTP協議存在一個Set-Cookie 的頭部字段,服務器可以通過Set-Cookie 頭部字段將Cookie發送給客戶端。例如下面這個例子:

      Set-Cookie: username=abc; expires=Wed, 09 Jun 2023 10:18:14 GMT; path=/
      

      在這個例子中,服務器設置了一個名為usernameCookie,它的值是abc,過期時間是2023年6月9日,路徑為/ 。瀏覽器在接收到該Cookie 時,便將其保存起來。

      客戶端請求時攜帶Cookie的方式,則是通過HTTP協議中的Cookie頭部字段,客戶端可以通過該頭部字段攜帶信息給服務器端,比如下面這個例子:

      Cookie: sessionid=1234
      

      在這個例子中,HTTP請求中攜帶了一個namesessionidvalue1234Cookie。當服務器端接收到該HTTP 請求后,從中解析出Cookie的信息,然后基于此實現后續的流程。

      3.2 實現說明

      回看上述流程,主要分為兩個大部分: 客戶端和服務器端。在客戶端部分,關鍵任務包括保存瀏覽器返回的Cookie信息以及在請求時攜帶Cookie 信息給服務器。對于服務器端,則是在通過身份校驗之后,能夠按照規范客戶端返回Cookie,并在接收到請求時,能夠正確解析出請求中的 Cookie 信息,識別出用戶信息。

      對于客戶端部分,在瀏覽器接收到HTTP響應時,如果響應體中有Set-Cookie 頭部字段,瀏覽器會自動保存Cookie信息;客戶端發起請求時,需要將 Cookie 信息傳遞給服務器。此時瀏覽器會自動攜帶通過校驗的Cookie。如果通過校驗,此時會在HTTP請求頭中攜帶Cookie信息給服務端,下面是一個大概的校驗流程:

      image.png

      在整個流程中,客戶端保存Token信息和在請求時攜帶Token信息這兩部分工作,瀏覽器已經幫我們實現了。剩下的工作集中在服務端的,主要涉及按照Cookie的規范給客戶端返回用戶標識,并在接收到客戶端請求時從HTTP請求中讀取Cookie以獲取到用戶的信息。與Cookie相關的詳細內容可以參考文章一文讀懂Cookie

      因此下面我們需要做的兩件事情,其一,服務器需要按照Cookie的規范往客戶端發送Cookie的內容;其次,服務器在處理請求時,需要從HTTP請求頭中讀取出Cookie的信息,成功識別用戶身份。

      Gin 框架中提供了一些API,能夠幫助我們在服務端,按照Cookie規范給客戶端發送Cookie 信息,同時也有API 能夠幫助我們解析Cookie 的信息。下面我們先來了解相關的API,然后再基于這些API ,搭建一個能夠自動識別用戶信息的 Web 應用程序。

      3.3 API說明

      3.3.1 SetCookie

      gin.Context 對象中的 SetCookie 方法用于向客戶端返回響應的同時,在Set-Cookie頭部攜帶Cookie 信息。下面是該方法的詳細說明:

      func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)
      
      • name:cookie 的名稱(必須)。
      • value:cookie 的值(必須)。
      • maxAge:cookie 的過期時間,以秒為單位。如果為負數,則表示會話 cookie(在瀏覽器關閉之后刪除),如果為零,則表示立即刪除 cookie(可選,默認值為-1)。
      • path:cookie 的路徑。如果為空字符串,則使用當前請求的 URI 路徑作為默認值(可選,默認值為空字符串)。
      • domain:cookie 的域名。如果為空字符串,則不設置域名(可選,默認值為空字符串)。
      • secure:指定是否僅通過 HTTPS 連接發送 cookie。如果為 true,則僅通過 HTTPS 連接發送 cookie;否則,使用 HTTP 或 HTTPS 連接都可以發送 cookie(可選,默認值為 false)。
      • httpOnly:指定 cookie 是否可通過 JavaScript 訪問。如果為 true,則無法通過 JavaScript 訪問 cookie;否則,可以通過 JavaScript 訪問 cookie(可選,默認值為 true)。

      在處理函數中,通過調用SetCookie 方法,便可以向客戶端發送一個HTTP cookie。這里舉一個代碼示例,來幫助讀者更好得理解該API,下面舉一個代碼示例,如下:

      func main() {
        router := gin.Default()
        
        router.GET("/set-cookie", func(c *gin.Context) {
          c.SetCookie("user", "john", 3600, "/", "", false, true)
          c.String(http.StatusOK, "cookie set successfully")
        })
        
        router.Run(":8080")
      }
      

      在這個示例中,使用 SetCookie 方法設置一個名為user的 cookie。這個 cookie 的值是john,在 1 小時后過期。該代碼還設置了路徑為“/”以及HttpOnly屬性為true。

      下面啟動該服務器,客戶端向服務端發送請求,請求路徑為/set-cookie,上面的處理函數將會被執行,然后我們來看其響應內容:

      # 1. 發送請求
      curl -i http://localhost:8080/set-cookie
      # 2. 返回響應
      HTTP/1.1 200 OK
      Content-Type: text/plain; charset=utf-8
      Set-Cookie: user=john; Path=/; Max-Age=3600; HttpOnly
      Date: Sun, 20 Aug 2023 07:39:15 GMT
      Content-Length: 23
      
      cookie set successfully
      

      查看上面第6行,可以看到,我們通過SetCookie方法,成功設置了一個Cookie,然后以在HTTP頭部的形式返回。

      3.1.2 Cookie方法

      往客戶端返回Cookie后,瀏覽器會將Cookie保存起來,然后在下次請求時將Cookie跟隨請求一起發送給服務器端。

      在HTTP無狀態協議的情況下,我們使用Cookie 來識別用戶信息,此時服務器端需要正確解析出HTTP 頭部中Cookie的信息,Gin 框架中的gin.Context 提供了Cookie方法,方便我們獲取到Cookie的信息。下面是該方法的定義說明:

      func (c *Context) Cookie(name string) (string, error) 
      

      使用Cookie方法可以獲取指定名稱的Cookie值,如果不存在指定名字的Cookie,此時將會返回錯誤。下面給一個簡單示例代碼的說明:

      func main() {
          router := gin.Default()
      
          // 定義路由
          router.GET("/cookie", func(c *gin.Context) {
              // 獲取名為 "username" 的 cookie
              cookie, err := c.Cookie("username")
              if err != nil {
                  // 如果 cookie 不存在,則返回錯誤信息
                  c.JSON(http.StatusBadRequest, gin.H{"error": "Bad request"})
                  return
              }
      
              // 在響應中返回 cookie 值
              c.JSON(http.StatusOK, gin.H{"username": cookie})
          })
      
          router.Run(":8080")
      }
      

      在上述示例中,我們定義了一個 /cookie 路由,使用 c.Cookie("username") 方法來獲取名為 username 的 Cookie 值。如果 Cookie 不存在,則返回一個錯誤響應。否則,我們將在響應中返回 Cookie 的值。

      下面我們通過curl 命令來對/cookie 請求,通過 -b 標識來攜帶cookie 值:

      # -v, --verbose 這個參數會打開curl的詳細模式,輸出一些額外的信息,包括HTTP請求和響應頭信息。
      curl -b -v -b "username=hello cookie;" http://localhost:8080/cookie
      

      下面我們來看具體的請求體和響應體的內容:

      GET /cookie HTTP/1.1
      Host: localhost:8080
      User-Agent: curl/7.79.1
      Accept: */*
      Cookie: username=hello cookie;
      

      可以看到,我們請求體攜帶了Cookie 字段,Cookie 的名稱為 username,我們前面服務器端便是嘗試獲取名為 username 的 Cookie,下面我們看請求的響應體,看是否成功解析了HTTP 請求 Cookie的內容:

      HTTP/1.1 200 OK
      Content-Type: application/json; charset=utf-8
      Date: Sun, 20 Aug 2023 08:12:45 GMT
      Content-Length: 27
      
      {"username":"hello cookie"}
      

      可以看到,服務端程序通過Cookie方法成功解析了HTTP請求頭部中Cookie字段的值,然后將解析的結果正常返回客戶端。

      3.4 代碼實現

      下面我們來搭建一個基于Cookie 實現用戶身份驗證的Web 應用程序,首先需要一個登錄頁面,用于驗證用戶身份信息,驗證通過后,我們將通過Cookie 給客戶端返回一個 Token

      同時,我們還需要創建一個頁面,需要驗證用戶身份信息,在驗證過程中,我們會檢查用戶請求中是否攜帶Cookie,同時Cookie 中攜帶的數據是否正確,基于此實現用戶身份的驗證。下面是一個簡單代碼的示例:

      func main() {
         route := gin.Default()
         
         route.GET("/login", func(c *gin.Context) {
            // HTTP 響應中攜帶 Cookie
            // Set cookie {"label": "ok" }, maxAge 30 seconds.
            c.SetCookie("label", "ok", 30, "/", "localhost", false, true)
            c.String(200, "Login success!")
         })
      
         route.GET("/home", func(c *gin.Context) {
            // 獲取 name = label 的 Cookie 的 value
            if cookie, err := c.Cookie("label"); err == nil {
               // 判斷 Cookie的value 是否滿足預期
               if cookie == "ok" {
                  c.JSON(200, gin.H{"data": "Your home page"})
               }
            } else {
               c.JSON(http.StatusForbidden, gin.H{"error": "Forbidden with no cookie"})
            }
         })
      
         route.Run(":8080")
      }
      

      首先是一個/login 請求路由,通過SetCookie 方法給客戶端返回Cookie,基于此返回用戶Token

      然后/home 路由的處理,則是通過gin.ContextCookie 方法獲取到HTTP請求頭部中Cookie的信息 ,然后驗證Cookie 中的value是否滿足預期。

      這個是一個簡單的代碼示例,比如用戶身份認證機制等,則需要自行完善,這里不再完整展示。

      4. 原理

      下面將簡單描述gin.Context 對象中SetCookie 方法和Cookie方法的實現原理,幫助讀者更好使用這兩個API

      4.1 SetCookie方法

      SetCookie 方法的實現原理如下,首先,SetCookie 方法會創建一個http.Cookie對象,并設置其名稱、值、路徑、域名、過期時間等屬性。例如,以下代碼創建了一個名為sessionidCookie:

      cookie := &http.Cookie{
          Name:    "sessionid",
          Value:   "1234",
          Expires: time.Now().Add(24 * time.Hour),
          Path:    "/",
          Domain:  "",
          Secure:  false,
          HttpOnly:true,
      }
      

      接下來,將上述Cookie對象轉換為字符串格式,并設置到HTTP響應頭的Set-Cookie字段中。代碼實現如下:

      func SetCookie(w ResponseWriter, cookie *Cookie) {
         if v := cookie.String(); v != "" {
            w.Header().Add("Set-Cookie", v)
         }
      }
      

      這里第三行將Cookie 存儲到Header 對象當中,Header 是專門用于存儲HTTP響應頭部的信息。調用Add 方法時,會根據指定的Key,在 Header 對象中查找相應的值列表。如果這個鍵不存在,則會在 Header 對象中創建一個新的值列表;否則,會在已有的值列表末尾添加新的值,大概流程如下:
      image.png

      在返回HTTP響應時,會遍歷Header 對象,填充HTTP響應頭部信息,然后返回給客戶端,比如上面Header 生成的HTTP響應頭部如下:

      Set-Cookie: v1
      Set-Cookie: v2
      Agent: Windows
      

      SetCookie 方法便是通過上述所說流程,將Cookie 的信息設置到HTTP響應體頭部當中去,然后返回給客戶端。

      4.2 Cookie方法

      在調用 Cookie() 方法時,系統會首先檢查請求頭部中是否包含名為 Cookie的字段。如果該字段不存在,則返回空字符串。

      如果請求頭部中包含 Cookie 字段,同時Cookiename 為調用Cookie() 方法指定的值,則系統會解析該字段并將其轉換為一個 http.Cookie 對象。這個對象包含了所有的 Cookie 屬性,例如名稱、值、路徑、過期時間、域名等等。最后,返回轉換后的http.Cookie 對象中值,大概流程如下:

      image.png

      總的來說,Cookie() 方法的實現原理比較簡單,它只是通過查找 HTTP 請求頭部中的 Cookie 信息,并將其轉換為 http.Cookie 對象來獲取請求中特定 Cookie 值。

      5. 總結

      在本文中,我們深入探討了Web應用程序在處理用戶信息時所面臨的挑戰,特別是在HTTP協議作為無狀態協議的背景下。我們從這一矛盾出發,介紹了解決方案中的Token機制,并引出了基于Cookie的實現方案。

      我們詳細闡述了Cookie的規范,包括服務端如何發送Cookie以及客戶端如何在請求中攜帶Cookie信息。

      我們進一步深入探討了具體的實現方式,并介紹了Gin框架提供的API,這些API使得在服務端按照Cookie規范發送和解析Cookie變得更加容易。通過一個實際的代碼示例,我們演示了如何使用這些API來構建一個基于Cookie實現用戶身份驗證的Web應用程序。

      在探討API的使用之余,我們也深入剖析了Gin框架提供的API的實現原理,為讀者提供了更深層次的理解。

      基于此,完成了對Gin中Cookie支持的介紹,希望對你有所幫助。

      posted @ 2023-08-23 07:01  菜鳥額  閱讀(1123)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 欧美videos粗暴| 国产视频有码字幕一区二区| 丰满少妇被猛烈进入av久久| 在线看片免费人成视频久网| 亚洲欧美一区二区成人片| 国产精品一区二区小视频| 欧美片内射欧美美美妇| 免费看婬乱a欧美大片| 护士张开腿被奷日出白浆| 色综合中文综合网| 人妻精品动漫h无码| 国产目拍亚洲精品二区| 久久精品无码专区免费东京热| 国产精品疯狂输出jk草莓视频| a在线免费| 狠狠干| 激情综合色综合久久丁香| 亚洲第一无码专区天堂| 欧美成人va免费大片视频| 国产免费无遮挡吸奶头视频| 青青草成人免费自拍视频| 亚洲av色香蕉一区二区| 国产精品久久久久久无毒不卡| 亚洲精品日韩在线丰满| 久久成人国产精品免费软件| 人妻体内射精一区二区三区| 蜜臀av久久国产午夜| 色婷婷综合久久久久中文一区二区| 欧美福利在线| 年轻女教师hd中字3| 国产乱码1卡二卡3卡四卡5| 日韩在线视频线观看一区| 无码人妻精品一区二区三区下载| 国产不卡一区不卡二区| 男女裸交免费无遮挡全过程| 精品国产一区二区三区性色| 日本一道一区二区视频| 中文国产不卡一区二区| 欧美人与动牲交a免费| 天堂网亚洲综合在线| 人成午夜免费视频无码|