session和cookie是网站浏览中较为常见的两个概念,也是比较难以辨析的两个概念,但它们在浏览需要认证的服务页面以及页面统计中却相当关键。我们先来了解一下session和cookie怎么来的?考虑这样一个问题:登录。
当用户来到微博登录页面,输入用户名和密码之后点击“登录”后浏览器将认证信息POST给远端的服务器,服务器执行验证逻辑,如果验证通过,则浏览器会跳转到登录用户的微博首页,在登录成功后,服务器如何验证我们对其他受限制页面的访问呢?因为HTTP协议是无状态的,所以很显然服务器不可能知道我们已经在上一次的HTTP请求中通过了验证。当然,最简单的解决方案就是所有的请求里面都带上用户名和密码,这样虽然可行,但大大加重了服务器的负担(对于每个request都需要到数据库验证),也大大降低了用户体验(每个页面都需要重新输入用户名密码,每个页面都带有登录表单)。既然直接在请求中带上用户名与密码不可行,那么就只有在服务器或客户端保存一些类似的可以代表身份的信息了,所以就有了cookie与session。
cookie,简而言之就是在本地计算机保存一些用户操作的历史信息(当然包括登录信息),并在用户再次访问该站点时浏览器通过HTTP协议将本地cookie内容发送给服务器,从而完成验证,或继续上一步操作。
但是使用cookie也有局限性,如果cookie很多,则会增加客户端与服务端的数据传输量。而且由于cookie数量的限制注定我们不能再cookie中保存过多的信息,于是session出现了。
session的作用就是在服务端保存一些用户信息,然后传递给用户一个特殊的cookie,这个cookie对应着服务端中的一个session,通过它就可以获取保存用户信息的session,进而就知道是哪个用户在发送信息。服务器使用session id来标识session,session id由服务器负责产生,保证随机性与唯一性,相当于一个随机密钥,避免在握手或传输中暴露用户真实密码。借助cookie机制来获取客户端的标识(即session id)。
上述意思可以概括为:
1,用户访问服务端,服务端对该用户创建一个session(可以理解为一个结构体,存储用户信息如表单),这个session结构体存储在服务端。
2,这个session有一个唯一的id,但是如何将这个id发送给用户呢,那就是使用cookie机制,服务端以响应头的方式发送给用户。
3,下回访问时,请求头中的Cookie字段中记录着session的id,也就知道了是这个用户。
Cookie代码展示
type Cookie struct { Name string Value string Path string Domain string Expires time.Time //设置过期时间 RawExpires string MaxAge int //设置过期时间
Secure bool
HttpOnly bool
SameSite SameSite
Raw string
Unparsed []string
}
String() string //将Cookie结构体以string形式返回
Valid() error //判断创建的Cookie对象是否合法
//Expires 和MaxAge都是设置过期时间。若没有设置时间则为临时cookie,在浏览器关闭的时候会自动清除。设置了时间,
//则会一直存在知道时间过期。
//两者的区别:Expires是设置时间点,明确的指出什么时候过期,如用户 16 Dec 2022 14:35:00访问服务端,此时cookie创建。
//服务端设置cookie有效时长为1小时,即Expires为16 Dec 2022 14:35:00.
//MaxAge则是指cookie被创建后能存活多少秒,用MaxAge设置的话则MaxAge为3600.
cookie := http.Cookie{Name: "username", Value: "123", Path: "/login", Domain: "127.0.0.1", Expires: time.Now().AddDate(0, 0, 1)}
//cookie常用的是Name,Value,Expires.
//time.Now().AddDate(0, 0, 1)是返回当前时间加(year,month,day)
fmt.Println(cookie.String())
fmt.Println(cookie.Valid())
结果:
username=123; Path=/login; Domain=127.0.0.1; Expires=Fri, 16 Dec 2022 14:35:43 GMT
<nil>
将Cookie发送至浏览器,从浏览器获取Cookie
Cookie结构体的String方法可以返回一个经序列化处理的cookie,响应头中的"Set-Cookie"字段的值就是这些序列化。
func main() { http.HandleFunc("/", setCookie) http.HandleFunc("/cookie", getCookie) http.ListenAndServe(":8080", nil) } func setCookie(w http.ResponseWriter, r *http.Request) { c1 := http.Cookie{ Name: "Tom", Value: "123456", HttpOnly: true, } c2 := http.Cookie{ Name: "Jack", Value: "123456", HttpOnly: true, } w.Header().Set("Set-Cookie", c1.String()) w.Header().Add("Set-Cookie", c2.String())
//设置响应头中的Cookie:使用Set()方法添加第一个cookie,使用Add方法添加第二个cookie。 } func getCookie(w http.ResponseWriter, r *http.Request) { cookie := r.Header["Cookie"]
//从请求头中的"Cookie"字段获得Cookie([]string类型)。 fmt.Fprintln(w, cookie) }
//先在浏览器中访问:127.0.0.1:8080/,生成cookie,
//再访问1270.0.1:8080/cookie从服务端获取cookie并在浏览器中显示。
结果:
http包中的cookie方法
//设置cookie
//func SetCookie(w ResponseWriter, cookie *Cookie) http.SetCookie(w, &c1) http.SetCookie(w, &c2) //获取cookie //func (r *Request) Cookie(name string) (*Cookie, error) cookie, err := r.Cookie("Tom")
//func (r *Request) Cookies() []*Cookie cookies := r.Cookies()
标签:http,string,会话,session,cookie,go,Cookie,服务端 From: https://www.cnblogs.com/dadishi/p/16986250.html