ing(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.Context
中Cookie
方法获取到HTTP请求头部中Cookie
的信息 ,然后验证Cooki