Cookie 和 Session

Cookie 和 Session

作用

  • 登录、购物车、游戏分数
  • 用户个性化信息、主题、其他设置
  • 记录和分析用户行为

服务器在返回网页内容的时候,使用 Set-Cookie 头来创建 Cookie

HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

[page content]
  • Session:浏览器关闭当前 Tab 页就过期
  • ExpiresMax-Age
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly
  • Secure:只有 HTTPS 协议的时候,浏览器端的 Cookie 才会上传到 Server
  • HttpOnly:声明这个的 Cookie,使用 Document.cokie 无法读和写
document.cookie = "yummy_cookie=choco"; 
document.cookie = "tasty_cookie=strawberry"; 
console.log(document.cookie); 

a.jd.com 能否共享 jd.com 的 Cookie? a.jd.comb.jd.com 呢?

同域名的二级域名可以实现共享,比如 www.domain.com 登陆后,在其他的二级域名,如 my.domain.combj.domain.comsh.domain.com 等二级域名都是可以共享登录的 Cookie 的。

mydomain.comsubdomain.mydomain.com 只能通过服务器端 Set-Cookie 头的方式来共享 Cookie;默认情况下,它们各自的 Cookie 的作用域都仅局限于请求的 Host,也称之为 Host-only Cookie。不过如果你主动设置了 domain

Set-Cookie: name=value; domain=mydomain.com

那么任何 mydomainsubdomain,都可以共享此 Cookie,比如 subsub.subdomain.mydomain.com。In RFC 2109, a domain without a leading dot meant that it 不能够 used on subdomains, and only a leading dot (.mydomain.com) would allow it to be used across multiple subdomains. However, all modern browsers respect the newer specification RFC 6265, and 会忽略任何的前缀 ., meaning you can use the cookie on subdomains as well as the top-level domain.

另外还有一个需要注意的点就是:从 subdomain.mydomain.com 返回的响应中带有 Set-Cookie: name=value; Domain=mydomain.com,是没有问题的;但是如果从 mydomain.com 返回的响应中带有 Set-Cookie: name=value; Domain=subdomain.mydomain.com,就会被浏览器拒绝掉这样的 Cookie。

Session

Java 服务器端的 Session 对象

如下是在 Java 中 javax.servlet.http.HttpSession 接口中的两个方法:

public interface HttpSession {

	void setAttribute(String name, Object value);
	Object getAttribute(String key);

}

在 Tomcat 中的 StandardSession 内部实现:

public class StandardSession implements HttpSession, Session, Serializable {

	protected ConcurrentHashMap<String, Object> attributes = new ConcurrentHashMap();

	@Override
	public void setAttribute(String name, Object value) {
		this.attributes.put(name, value);
	}

	@Override
	public Object getAttribute(String name) {
		return this.attributes.get(name);
	}

}

可见 Session 其实就是一个存储在服务器端的 Map ,它可以存储的对象为 Object

Session 默认有效期

在 Tomcat 中,Session 默认有效期是 30 秒:

<session-config>
  <session-timeout>30</session-timeout>
</session-config>
  • 安全性: Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的。
  • 存取值的类型不同:Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型。
  • 有效期不同: Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。
  • 存储大小不同: 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。

参考