文章目录
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,用户无需再手动进行登录,跳转回之前正在访问的服务,继续以登录态进行访问。