Cookie 属性详细解析

1,384 阅读2分钟

参考

developer.mozilla.org/en-US/docs/…

Set-Cookie 格式

<cookie-name>=<cookie-value> 

Expires=<date>
Max-Age=<non-zero-digit>

Domain=<domain-value>
Path=<path-value>

HttpOnly
Secure
SameSite={Strict|Lax}

增删改查



/**
 * 测试 Cookie 查询
 */
@GetMapping("/get")
public String get(HttpServletRequest req, HttpServletResponse resp)  throws Exception{
    Cookie[] cookies = req.getCookies();
    if(cookies == null || cookies.length == 0) {
        return "empty cookie";
    }

    StringBuilder sb = new StringBuilder();
    for (Cookie c : cookies) {
        String info = String.format("name=%s, value=%s, domain=%s, path=%s, maxAge=%s, httpOnly=%s, secure=%s",
                c.getName(), c.getValue(), c.getDomain(), c.getPath(), c.getMaxAge(), c.isHttpOnly(), c.getSecure());
        sb.append(info).append("\n");
    }
    return sb.toString();
} /*
// 不能访问到名称为 aa 的cookie, 因为 path 为 /cookie/path
name=bb, value=1560325032038, domain=null, path=null, maxAge=-1, httpOnly=false, secure=false
*/


/**
 * 添加 cookie
 * httpOnly = true , 安全考虑
 * path = /, 可见性
 */
@GetMapping("/add")
public String add(HttpServletRequest req, HttpServletResponse resp) {
    Cookie cookie = new Cookie("foo", "bar");
    cookie.setHttpOnly(true);
    cookie.setPath("/");
    resp.addCookie(cookie);
    return System.currentTimeMillis() + "";
}


/**
 * 更新 Cookie
 * name 和 path 必须一致
 * value: 新值
 * maxAge: 不必理会
 *
 */
@GetMapping("/update")
public String update(HttpServletRequest req, HttpServletResponse resp) {
    Cookie cookie = new Cookie("foo", System.currentTimeMillis() + "");
    cookie.setHttpOnly(true);
    cookie.setPath("/");
    resp.addCookie(cookie);
    return System.currentTimeMillis() + "";
}

/**
 * 删除 Cookie
 * name 和 path 必须一致
 * value: 不必理会
 * maxAge: 0 表示删除
 */
@GetMapping("/remove")
public String remove(HttpServletRequest req, HttpServletResponse resp) {
    Cookie cookie = new Cookie("foo", System.currentTimeMillis() + "");
    cookie.setHttpOnly(true);
    cookie.setPath("/");
    cookie.setMaxAge(0);
    resp.addCookie(cookie);
    return System.currentTimeMillis() + "";
}




Domain

该域名和子域的 cookie 都可以访问

Path

cookie 的默认路径尤其要注意。 一般都要强制写上 /, 否则默认为生成 cookie 的路径 。


/**
 * 测试 cookie 路径问题
 * 没有指定路径默认为当前路径: /cookie/path
 * 该路径及子路径可以访问到这 cookie
 */
@GetMapping("/path/foo")
public String path(HttpServletRequest req, HttpServletResponse resp) {
    String value = System.currentTimeMillis()+"";

    Cookie aa = new Cookie("aa",value);
    Cookie bb = new Cookie("bb",value);
    bb.setPath("/");

    resp.addCookie(aa);
    resp.addCookie(bb);
    return value;
}


/*
 * 输出这个请求能获取到的所有 cookie
 */
@GetMapping("/get")
public String get(HttpServletRequest req, HttpServletResponse resp)  throws Exception{
    Cookie[] cookies = req.getCookies();
    if(cookies == null || cookies.length == 0) {
        return "empty cookie";
    }

    StringBuilder sb = new StringBuilder();
    for (Cookie c : cookies) {
        String info = String.format("name=%s, value=%s, domain=%s, path=%s, maxAge=%s, httpOnly=%s, secure=%s",
                c.getName(), c.getValue(), c.getDomain(), c.getPath(), c.getMaxAge(), c.isHttpOnly(), c.getSecure());
        sb.append(info).append("\n");
    }
    return sb.toString();
} /*
// 不能访问到名称为 aa 的cookie, 因为 path 为 /cookie/path
name=bb, value=1560325032038, domain=null, path=null, maxAge=-1, httpOnly=false, secure=false
*/


HttpOnly

需要 http 才能使用这个 cookie


/**
 * 测试 cookie httpOnly 属性
 * cookie 设置 httpOnly 为 true, document.cookies 将获取不到这个 cookie
 */
@GetMapping("/httpOnly")
public String httpOnly(HttpServletRequest req, HttpServletResponse resp) {
    String value = System.currentTimeMillis()+"";

    Cookie aa = new Cookie("aa",value);
    Cookie bb = new Cookie("bb",value);
    bb.setHttpOnly(true);

    resp.addCookie(aa);
    resp.addCookie(bb);
    return value;
}

chrome 控制台测试


> document.cookie
"aa=1560325032038"

Secure

需要 https 才能使用这个 cookie


/**
 * 测试 cookie secure 属性
 * 需要 https 请求才能访问在这个 cookie
 */
@GetMapping("/secure")
public String secure(HttpServletRequest req, HttpServletResponse resp) {
    String value = System.currentTimeMillis()+"";

    Cookie aa = new Cookie("aa",value);
    Cookie bb = new Cookie("bb",value);
    bb.setSecure(true);

    resp.addCookie(aa);
    resp.addCookie(bb);
    return value;
}