http cookie

HTTP Cookie(也叫Web Cookie或浏览器Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。

cookie的本质就是http的cookie Header里面写的数据

例如访问官网,chrome78网络请求里面的活动请求header,在cookie header第一段数据就是__utmc=110886291,就是一个cookie的键值数据。

:authority: golang.org
:method: GET
:path: /
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9,en;q=0.8
cache-control: no-cache
cookie: __utmc=110886291; __utmz=110886291.1575179973.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _ga=GA1.2.284134183.1575179973; _gid=GA1.2.1463361514.1575348908; __utma=110886291.284134183.1575179973.1575367986.1575386541.4; __utmt=1; __utmb=110886291.1.10.1575386541
dnt: 1
pragma: no-cache
sec-fetch-mode: navigate
sec-fetch-site: none
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36

名称

键名

作用

名称

Name

cookie的名称

内容

Value

cookie的值

域名

Domain

cookie存在的域名

路径

Path

指定uri路径之下生效

过期时间

Expire

失效时间

是否安全

Secure

是否只能用于https

是否仅用于http

HttpOnly

是否仅用于http传输 true时阅览器document无法读取

http

在http协议中,agent请求时候一般会自动添加Cookie Header,值就是cookie键值对。

如果服务端修改cookie,在Response Header里面会有Set-Cookie Header,agent会根据值来修改自身cookie。

通过查看http请求和响应或者抓包可以发现,请求cookie header就是服务端收到的cookie数据,而服务端设置cookie后,响应里面就有set-cookie header,值就是服务端设置的属性。

详细情况请看rfc

简单来说cookies就是阅览器里面一个叫做document.cookie的全局字符串对象

进入阅览器控制台输入console.log(document.cookie),回车执行就可以看见当前站点的cookies。

发现cookies就是一段序列化的键值字符串,如果需要操作cookie,则是通过操作document.cookie字符串来达到效果。

阅览器中cookies会随http请求自动发送,在request中会有cookie和Set-Cookie这两个header,里面就是cookie,h5的fetch需要指定是否发送cookies,默认不发送cookies

js操作cookie数据,直接读写document.cookie对象,封装函数如下:

"use strict";
function getCookie(name){
    var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
    if(arr = document.cookie.match(reg))
        return unescape(arr[2]);
    else
        return null;
}

function setCookie(name, value, expiredays){
    var exp = new Date();
    exp.setDate(exp.getDate() + expiredays)
    document.cookie = name + "=" + escape(value) + ((expiredays==null) ? "" : ";expires=" + exp.toGMTString())
}

function delCookie(name){
    var exp = new Date();
    exp.setTime(exp.getTime() - 1);
    document.cookie = name + "=;expires=" + exp.toGMTString();
}

net/http.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 
}

查看net/http定义的函数,可以发现读Cookie实现是读取Request.Header里面的Cookie header;而修改Cookie就设置ResponseWriter.Header()里面的Set-Cookie header,例如setcookie。

Example

操作cookie


cookie := http.Cookie{Name: "testcookiename", Value: "testcookievalue", Path: "/", MaxAge: 86400}
http.SetCookie(w, &cookie)


cookie, err := req.Cookie("testcookiename")


cookie := http.Cookie{Name: "testcookiename", Path: "/", MaxAge: -1}
http.SetCookie(w, &cookie)

Get

net/http.Request.Cookies() []*Cookie方法就是通过读取net/http.Request.Header["cookie"]的值,分析出cookie键值对来构造cookie,每次读取cookie都会出来一次,效率调低。

readCookies函数过长不列出。

Set

net/http.SetCookie(w ResponseWriter, cookie *Cookie)方法定义,直接将要设置的cookie序列化成字符串,给response添加Set-Cookie Header,添加多个Cookie就将Set-Cookie Header添加多次。

net/http.Cookie.Srting()方法就是Cookie对象的序列化的方法,会将多种属性组合成字符串。

例如:路径、域名、过期时间、只读、仅https这些属性。

以下是SetCookie和修改请求Cookie的AddCookie函数实现:




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





func (r *Request) AddCookie(c *Cookie) {
    s := fmt.Sprintf("%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value))
    if c := r.Header.Get("Cookie"); c != "" {
        r.Header.Set("Cookie", c+"; "+s)
    } else {
        r.Header.Set("Cookie", s)
    }
}

安全

XSS

XSS触发后盗取cookie信息,然后使用Cookie信息操作。

CSRF

cookie是CSRF两种基本触发条件之一。

Last updated

Was this helpful?