Cookie那些事儿(Cookie跨域、Cookie共享、SSO)

1、什么是Cookie

HTTP 是无状态的协议,每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人。所以服务器与浏览器为了进行会话跟踪(知道是谁在访问我),就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。Cookie是服务器发送到用户浏览器并保持在本地的一小块信息,他会在浏览器下次向服务器发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器。

在这里插入图片描述

2、Cookie的生命周期

	Cookie保存在浏览器(客户端)中
	
	如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。
	
	如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。

3、Cookie有什么用?

Cookie被广泛用于管理用户的会话状态。当用户登录网站时,服务器可以创建一个包含用户标识的Cookie,并在后续的请求中使用该Cookie来识别用户,从而实现用户的登录状态保持。

登录逻辑

  • 用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session ,response时将此 Session 的唯一标识信息 SessionID 返回给浏览器,浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名。
  • 当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,
  • 只有找到 Session 才可以证明用户已经登录, 就可执行后面操作。

4、基于java的Cookie工具类

public class CookieUtil {

	// 默认缓存时间,单位/秒, 2H
	private static final int COOKIE_MAX_AGE = Integer.MAX_VALUE;
	// 保存路径,根路径
	private static final String COOKIE_PATH = "/";
	
	/**
	 * 保存
	 *
	 * @param response
	 * @param key
	 * @param value
	 * @param ifRemember 
	 */
	public static void set(HttpServletResponse response, String key, String value, boolean ifRemember) {
		int age = ifRemember?COOKIE_MAX_AGE:-1;
		set(response, key, value, null, COOKIE_PATH, age, false);
	}

	/**
	 * 保存
	 *
	 * @param response
	 * @param key
	 * @param value
	 * @param maxAge
	 */
	private static void set(HttpServletResponse response, String key, String value, String domain, String path, int maxAge, boolean isHttpOnly) {
		Cookie cookie = new Cookie(key, value);
		if (domain != null) {
			cookie.setDomain(domain);
		}
		cookie.setPath(path);
		cookie.setMaxAge(maxAge);
		cookie.setHttpOnly(isHttpOnly);
		response.addCookie(cookie);
	}
	
	/**
	 * 查询value
	 *
	 * @param request
	 * @param key
	 * @return
	 */
	public static String getValue(HttpServletRequest request, String key) {
		Cookie cookie = get(request, key);
		if (cookie != null) {
			return cookie.getValue();
		}
		return null;
	}

	/**
	 * 查询Cookie
	 *
	 * @param request
	 * @param key
	 */
	private static Cookie get(HttpServletRequest request, String key) {
		Cookie[] arr_cookie = request.getCookies();
		if (arr_cookie != null && arr_cookie.length > 0) {
			for (Cookie cookie : arr_cookie) {
				if (cookie.getName().equals(key)) {
					return cookie;
				}
			}
		}
		return null;
	}
	
	/**
	 * 删除Cookie
	 *
	 * @param request
	 * @param response
	 * @param key
	 */
	public static void remove(HttpServletRequest request, HttpServletResponse response, String key) {
		Cookie cookie = get(request, key);
		if (cookie != null) {
			set(response, key, "", null, COOKIE_PATH, 0, true);
		}
	}

}
  • new Cookie(String name, String value):创建一个Cookie对象,必须传入cookie的名字和cookie的值
  • getValue():得到cookie保存的值
  • getName():获取cookie的名字
  • setMaxAge(int expiry):设置cookie的有效期,默认为-1。这个如果设置负数,表示客服端关闭,cookie就会删除。0表示马上删除。正数表示有效时间,单位是秒。
  • setPath(String uri):设置cookie的作用域
  • response.addCookie(Cookie cookie):将cookie给客户端进行保存
  • resquest.getCookies():得到客服端传过来的所有cookie对象

HttpOnly标志:值为true时,Cookie只会在Http请求头中存在,不能通过doucment.cookie;(JavaScript)访问Cookie。。

5、什么是域?

在应用模型,一个完整的,有独立访问路径的功能集合称为一个域。例如百度称为一个应用或系统,下面有若干的域,如:搜索引擎(www.baidu.com)、百度贴吧(tie.baidu.com)、百度知道(zhidao.baidu.com)、百度地图(map.baidu.com)等。

6、什么是跨域?

浏览器对于javascript的同源策略的限制。
客户端请求的时候,请求地址的协议,ip地址,端口号三者只要有一个和当前的不一样就是跨域。
例如:在www.jd.com页面,点击手机后,请求地址就变成了search.jd.com,DNS会将域名映射为对应的IP地址,将请求打到对应的服务器上。这就是一次跨域。

跨域的几种类型

a.com和b.com(一级域名跨域)
qq.a.com和ww.a.com(二级域名跨域)
http://a.com和https://a.com: http和https也属于跨域
示例:

当前页面url被请求页面url是否跨域原因
http://www.test.com/http://www.test.com/index.html同源(协议、域名、端口号相同)
http://www.taobao.com/https://www.taobao.com/跨域协议不同(http/https)
http://www.test.com/http://www.baidu.com/跨域主域名不同(test/baidu)
http://www.test.com/http://blog.test.com/跨域子域名不同(www/blog)
http://www.test.com:8080/http://www.test.com:7001/跨域端口号不同(8080/7001)

7、Cookie的域(Domain)

Cookie的域(Domain)指定了哪些域名可以访问这个Cookie。
当设置Cookie时,你可以使用domain属性来指定允许访问该Cookie的域名范围。这个属性可以设置为当前域名或它的父域名。例如,当前的域名为:‘sub1.example.com’,如果你将Domain属性设置为’.example.com’,那么该Cookie将在example.com及其所有子域名中可见。而不可以指定sub2.example.com或者subchild.sub1.example.com

如果你在sub.example.com域名下设置了一个Cookie,那么它将在sub.example.com及其子域名下可见,但不会在父域名example.com下可见。这是出于安全和隐私方面的考虑,以确保不同子域名之间的信息不会相互干扰。

例如:域A为t1.example.com,域B为t2.example.com,那么在域A生产一个令域A和域B都能访问的cookie就要将该cookie的domain设置为.example.com;如果要在域A生产一个令域A不能访问而域B能访问的cookie就要将该cookie的domain设置为t2.example.com。

如何算共享了cookie :

同一个域下所有请求 ,都会携带cookie去服务器请求数据
所以我们拿到一个网站的cookie , 就相当于掌握了整个网站的登录钥匙
一般模式下两个网站的cookie不共享 , 防止A网站服务器端可以拿到B网站服务器的数据,相当于我在京东登录后,到了淘宝还是要登录。

允许跨域的常用功能 — 单点登录

单点登录:在A域名登录 , B C D等合作网站就无需再登录 , 可以直接打开网页的内容
单点登录的原理:
同一个浏览器下 ,在登录域第一次请求服务器后 , 拿到了钥匙 , 我们将cookie设置为共享 (我们可以指定将cookie共享给哪些域) , 这样其他域的token过期后,跳转到SSO进行登录时,如果登录域的cookie还没过期,其他的域拿到了登录域的cookie,用户无需再手动进行登录,跳转回之前正在访问的服务,继续以登录态进行访问。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值