Cookie是什么
- HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分两次请求是否由同一个客户端发出。
- Cookie就是解决HTTP协议无状态的方案之一,中文是小甜饼的意思。
- Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了Cookie之后,每次向服务器发送请求时都会同时将该信息发送给服务器,服务器收到请求后,就可以根据该请求处理请求。
- Cookie由服务器创建,并发送给浏览器,最终由浏览器保存。
Cookie的用途
- 保持用户登录状态。
- 无登录状态下的电商购物车
Cookie的使用
服务端发送cookie给客户端,客户端请求时携带cookie
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("cookie", func(c *gin.Context) {
name := "cookieKey"
cookie, err := c.Cookie(name)
if err != nil {
cookie = "notSet"
value := "cookieSet"
c.SetCookie(name, value, 60, "/", "localhost", false, true)
}
fmt.Printf("cookie: %#v\n", cookie)
})
_ = r.Run()
}
Cookie的练习
- 模拟实现权限验证中间件
- 有2个路由,login和home
- login用于设置cookie
- home用于访问查看信息请求
- 在请求home之前,先执行中间件代码,检验是否存在cookie
- 尝试一下操作
- 第一步,访问home,收到返回JSON {"error": "status_unauthorized"}
- 第二步,访问login,收到返回字串 "login successful"
- 第三部,访问home,收到返回JSON {"data": "home"}
以下是实现的代码:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func AutoMiddleware() (handler gin.HandlerFunc) {
handler = func(c *gin.Context) {
if cookie, err := c.Cookie("abc"); err == nil {
if cookie == "123" {
c.Next()
return
}
}
c.JSON(http.StatusUnauthorized, gin.H{"error": "status_unauthorized"})
c.Abort()
}
return
}
func main() {
r := gin.Default()
r.GET("/login", func(c *gin.Context) {
c.SetCookie("abc", "123", 60, "/", "localhost", false, true)
c.String(http.StatusOK, "login successful")
})
r.GET("/home", AutoMiddleware(), func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"data": "home"})
})
_ = r.Run()
}
Cookie的缺点
- 不安全,明文
- 增加宽带消耗
- 可以被禁用
- cookie有上限
Session是什么
Session可以弥补cookie的不足,不过session必须依赖于cookie才能使用,做法是生成一个session_id放在cookie中,一同传给客户端。