前后端不分离的场景下使用比较多。
cookie
cookie由来
HTTP协议是无状态的,这就存在一个问题。
无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无关系,它不会受前面的请求响应情况直接影响,也不会影响后面的请求响应情况。
一句话来说,就是对服务器来说,每次请求都是全新的。
状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态就以为这些数据不会保留。会话中产生的数据又是需要我们保存的,也就是要“保持状态”。所以cookie就是在这样一个场景下诞生。
Cookie是什么
在Internet中,Cookie实际上是指小量信息,是由web服务器创建的,将信息存储在用户计算机(客户端)的数据文件。一般网络用户习惯用其复数形式Cookies,指某些网站为了辨别用户身份,进行Session跟踪而存储在用户本地终端上的数据,这些数据会加密处理。
Cookie的机制
Cookie是由服务器端生成,发送给User-Agent(一般指浏览器),浏览器会将Cookie的key/value保存在某个目录下的文本文件,下次请求统一网站时,就发送该cookie到服务器(前提浏览器默认启用cookie)。cookie名称和值可以由服务端开发自己定义,这样服务器可以知道该用户是否合法用户以及是否需要重新登录等,服务器可以设置或读取cookies中包含信息,借此维护用户跟服务器会话中的状态。
总结下Cookie的特点:
1、浏览器发送请求的时候,自动携带该站点之前存储的cookie的信息.
2、服务端可以设置cookie数据。
3、cookie时针对单个域名的,不同域名之间的cookie是独立的。
4、cookie数据可以配置过期时间,过期的cookie数据会被系统清楚。
查看cookie
使用chrome浏览器打开一个网站,打开开发者工具查看该网站保存在我们电脑上的cookie数据。
Go操作cookie
cookie
标准库net/http
中定义了cookie,它代表一个出现在HTTP响应头中set-cookie的值或者HTTP请求头中的cookie的值http cookie
。
type Cookie struct {
Name string
Value string
Path string
Domain string
Expires time.Time
RawExpires string
// MaxAge=0表示未设置Max-Age属性
// MaxAge<0表示立刻删除该cookie,等价于"Max-Age: 0"
// MaxAge>0表示存在Max-Age属性,单位是秒
MaxAge int
Secure bool
HttpOnly bool
Raw string
Unparsed []string // 未解析的“属性-值”对的原始文本
}
设置cookie
net/http
中提供了如下SetCookie
函数,它在w的头域中添加Set-Cookie头,该HTTP头的值为cookie。
func SetCookie(w ResponseWriter, cookie *Cookie)
获取Cookie
Request
对象拥有两个获取Cookie的方法和一个添加Cookie的方法:
获取Cookie的两种方法:
// 解析并返回该请求的Cookie头设置的所有cookie
func (r *Request) Cookies() []*Cookie
// 返回请求中名为name的cookie,如果未找到该cookie会返回nil, ErrNoCookie。
func (r *Request) Cookie(name string) (*Cookie, error)
添加Cookie的方法:
// AddCookie向请求中添加一个cookie。
func (r *Request) AddCookie(c *Cookie)
gin框架操作cookie
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/cookie", func(c *gin.Context) {
cookie, err := c.Cookie("gin_cookie") // 获取Cookie
if err != nil {
cookie = "NotSet"
// 设置Cookie
c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
}
fmt.Printf("Cookie value: %s \n", cookie)
})
router.Run()
}
Session
Session的由来
Cookie虽然在一定程度上解决了“保持状态的”需求,但是cookie本身支持最大4096字节,以及cookie本身保存在客户端,可能被拦截或窃取安,因此就需要一种新的东西,他能支持更多的字节,并且保存在服务端,有较高的安全性,这就是Session
。
问题来了,HTTP是无状态协议,服务器根本不知道访问者是谁。那么上述的cookie就起到桥接的作用。
用户登录成功后,我们在服务端为每个用户创建一个session和一个唯一的标识,他们一一对应。其中:
1、sesion是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;
2、唯一标识通常称为session id会写入用户的cookie中。
这样该用户后续再次访问,请求会自动携带cookie数据(sesssion id),服务器通过该session id就能找到与之对应的session数据。
总结:
cookie弥补了http无状态的不足,让服务器知道来的人是谁;但是cookie保存在客户端本地,自身安全性差;所以通过coookie识别不同用户,对应在服务端为每个用户保存一个session,该session数据中能够保存具体用户信息。