SSO基础之Cookie详解

 

这篇文章主要详解Cookie技术:百度百科介绍:cookie,储存在用户本地终端上的数据,指某些网站为了辨别...

这篇文章主要详解Cookie技术:

百度百科介绍:

cookie,储存在用户本地终端上的数据,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。

用途:

服务器可以利用Cookies包含信息的任意性来筛选并经常性维护这些信息,以判断在HTTP传输中的状态。Cookies最典型的应用是判定注册用户是否已经登录网站,用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续,这些都是Cookies的功用。另一个重要应用场合是“购物车”之类处理。用户可能会在一段时间内在同一家网站的不同页面中选择不同的商品,这些信息都会写入Cookies,以便在最后付款时提取信息。

Cookie是最早是网景公司的前雇员Lou Montulli在1993年3月的发明。Cookie是由服务器生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。Cookie名称和值可以由服务器端开发自己定义,对于JSP而言也可以直接写入jsessionid,这样服务器可以知道该用户是否是合法用户以及是否需要重新登录等,服务器可以设置或读Cookies中包含信息,借此维护用户跟服务器会话中的状态。

Java提供操作的Cookie的API如下:
Cookie类的主要方法
No.

方法

类型

描述

1

Cookie(String name, String value)

构造方法

实例化Cookie对象,传入cooke名称和cookie的值

2

public String getName()

普通方法

取得Cookie的名字

3

public String getValue()

普通方法

取得Cookie的值

4

public void setValue(String newValue)

普通方法

设置Cookie的值

5

public void setMaxAge(int expiry)

普通方法

设置Cookie的最大保存时间,即cookie的有效期,当服务器给浏览器回送一个cookie时,如果在服务器端没有调用setMaxAge方法设置cookie的有效期,那么cookie的有效期只在一次会话过程中有效,用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一次会话
当用户关闭浏览器,会话就结束了,此时cookie就会失效,如果在服务器端使用setMaxAge方法设置了cookie的有效期,比如设置了30分
钟,那么当服务器把cookie发送给浏览器时,此时cookie就会在客户端的硬盘上存储30分钟,在30分钟内,即使浏览器关了,cookie依然存
在,在30分钟内,打开浏览器访问服务器时,浏览器都会把cookie一起带上,这样就可以在服务器端获取到客户端浏览器传递过来的cookie里面的信
息了,这就是cookie设置maxAge和不设置maxAge的区别,不设置maxAge,那么cookie就只在一次会话中有效,一旦用户关闭了浏览
器,那么cookie就没有了,那么浏览器是怎么做到这一点的呢,我们启动一个浏览器,就相当于启动一个应用程序,而服务器回送的cookie首先是存在
浏览器的缓存中的,当浏览器关闭时,浏览器的缓存自然就没有了,所以存储在缓存中的cookie自然就被清掉了,而如果设置了cookie的有效期,那么
浏览器在关闭时,就会把缓存中的cookie写到硬盘上存储起来,这样cookie就能够一直存在了。

6

public int getMaxAge()

普通方法

获取Cookies的有效期

7

public void setPath(String uri)

普通方法

设置cookie的有效路径,比如把cookie的有效路径设置为"/xdp",那么浏览器访问"xdp"目录下的web资
源时,都会带上cookie,再比如把cookie的有效路径设置为"/xdp/gacl",那么浏览器只有在访问"xdp"目录下的"gacl"这个目
录里面的web资源时才会带上cookie一起访问,而当访问"xdp"目录下的web资源时,浏览器是不带cookie的

8

public String getPath()

普通方法

获取cookie的有效路径

9

public void setDomain(String pattern)

普通方法

设置cookie的有效域

10

public String getDomain()

普通方法

获取cookie的有效域

决定cookie内容、生命周期和有效范围的7个属性如下:

  1. name和value
  2. expires
  3. path和domain
  4. httpOnly和secure
以下分别来讲解该内容:

a.name和value

name和value分别代表cookie的名称和该cookie所代表的值,设置如下:

cookie = new Cookie(cookieBean.getName() , cookieBean.getValue());

其中我用cookieBean进行了一个封装处理。当使用response.addCookie(cookie);的时候实际是在响应头里面添加了这样的内容:相应头Set-Cookie,该相应头指定的内容cookieTest=2016/4/10; Expires=Sun, 10-Apr-2016 16:40:02 GMT; Path=/。这里的cookieTest就是name的值,2016/4/10就是value对应的值(后面的内容先不要管)。

有的时候我们value存的是中文名称,结果会怎么样呢?我讲value变为中文字符的时候直接报错如下(控制在cookie中value的值得属性):

Control character in cookie value or attribute.

思路:利用java中的编码和解码方式间接的存储中文。涉及到类URLEncoder,URLDecoder。

            //将中文转换为utf-8
String name = "冯超";

//编码 涉及到类  URLEncoder
String name_en = URLEncoder.encode(name, "utf-8");
System.out.println(name_en);

//解码 涉及到类 URLDecoder
name_en = URLDecoder.decode(name_en, "utf-8");
System.out.println(name_en);

在js中编码及解码操作:

            var name = "冯超";
var name_en = encodeURI(name);
alert(name_en);
//js中的解码
name_en = decodeURI(name_en);
alert(name_en);

关于API中的方法和参数详细查询API文档。

b.expires

expires代表cookie中的过期时间,java中API函数是setMaxAge(int expires), 源码中该参数的解释说明如下:

an integer specifying the maximum age of the cookie in seconds; if negative, mean the cookie is not stored; if zero, deletes the cookie。

翻译就是:在cookie中设置的一个整形的最大的值,单位是秒,如果是负数意味着cookie不存储,如果是0,则删除该cookie。默认值是-1.

c.path和domain

先来看path,在java中API的方法是cookie.setPath(String uri),该uri在源码中的解释是:

Specifies a path for the cookie to which the client should return the cookie.

The cookie is visible to all the pages in the directory you specify, and all

the pages in that directory's subdirectories. A cookie's path must include the

servlet that set the cookie, for example, /catalog, which makes the

cookie visible to all directories on the server under /catalog.

Consult RFC 2109 (available on the Internet) for more information on setting

path names for cookies.

翻译:一个特殊的路径决定了那一个客户端应该返回该cookie。例如如果设置的路径是/catalog,则在该路径下以及它的所有子目录该cookie都可见。API中的参数是URI,那URI指的是什么呢?英文全称是Uniform Resource Identifier,统一资源定位符。普及一下这方面的知识:



看这个图就指的就是我们常说是URL,统一资源标识符。其中javaEE中request对象有类似的API。

String url = request.getRequestURL().toString();
String uri = request.getRequestURI().toString();

URL就是指的:协议+主机名+(路径+文件名)

URL指的:除了协议+主机名后面的东西。

所以cookie.setPath(String uri).指的就是设置后面的路径,若uri="/",则是整个项目路径文件都可见。若是uri="/path" 则只有该path目录下或者子目录的文件该cookie才可见。

在来说说domain。在java中的API方式是setDomain(String domain),该domain参数在源码中的解释如下:

Specifies the domain within which this cookie should be presented.

The form of the domain name is specified by RFC 2109. A domain name begins

with a dot (

.foo.com
) and means that the cookie is visible to

servers in a specified Domain Name System (DNS) zone (for example,

www.foo.com
, but not
a.b.foo.com
). By default, cookies

are only returned to the server that sent them.

首先说个域名的的概念,例如:www.weixin.com。www表示的是万维网的开头,.com是域名后缀,常见的还有.net,.cn等。若还有个叫做www.a.weixin.com则表示的是上个域名的二级域名。

测试如下:

在自己的C:WindowsSystem32driversetc的hosts文件中设置2个域名指向本机ip:

127.0.0.1 www.a.com
127.0.0.1 www.b.a.com

此时www.b.a.com则就是www.a.com的二级域名,想www.a.com的项目中设置:

cookieBean.setMaxAge(60);
cookieBean.setName("domain");

cookieBean.setValue(CodeUtil.encode("doamin呵呵111", CodeUtil.CODE_UTF_8));
cookieBean.setPath("/");
cookieBean.setDomain(".a.com");

项目发布后,在二级域名www.b.a.com的页面中也能看到www.a.com项目中设置的cookie信息。

cookie.setDomain(String domain)表示的意思是,若你访问的是www.a.com/a.jsp.默认设置的是www.a.com.若你还有个www.b.a.com,你想要进行跨域访问的则设置.a.com即可。

d.httpOnly和secure

先来看httpOnly,在java中的API方式是setHttpOnly(boolean isHttpOnly),默认值是false。看看API源码中对它的解释:

Marks or unmarks this Cookie as HttpOnly.

If isHttpOnly is set to true, this cookie is marked as

HttpOnly, by adding the HttpOnly attribute to it.

HttpOnly cookies are not supposed to be exposed to client-side

scripting code, and may therefore help mitigate certain kinds of cross-site

scripting attacks.

翻译的意思大概就是:标记是否支持httpOnly,如果设置的httpOnly参数为true(默认是false),则将不支持在客户端的脚本那一边暴漏,因此能防止脚本的攻击。

引用一下网上的Cookie及XSS。

随着B/S的普及,我们平时上网都是依赖于http协议完成,而Http是无状态的,即同一个会话的连续两个请求互相不了解,他们由最新实例化的环境进行解
析,除了应用本身可能已经存储在全局对象中的所有信息外,该环境不保存与会话有关的任何信息,http是不会为了下一次连接而维护这次连接所传输的信息的。所以为了在每次会话之间传递信息,就需要用到cookie和session,无论是什么,都是为了让服务器端获得一个token来检查合法性,很多时候都是在cookie中存储一个sessionID,服务器来识别该用户,那么安全隐患也就引申而出了,只要获得这个cookie,就可以取得别人的身份,特别是管理员等高级权限帐号时,危害就大了,而XSS就是在别人的应用程序中恶意执行一段JS以窃取用户的cookie。

那么如何获得Cookie劫持呢?在浏览器中的document对象中,就储存了Cookie的信息,而利用js可以把这里面的Cookie给取出来,只要得到这个Cookie就可以拥有别人的身份了

如何用JavaScript获取cookie信息到了,W3C标准里面给出了答案:

function getCookieValue(cookieName) {
var cookieValue = document.cookie;
var cookieStartAt = cookieValue.indexOf("" + cookieName + "=");
if (cookieStartAt == -1) {
cookieStartAt = cookieValue.indexOf(cookieName + "=");
}
if (cookieStartAt == -1) {
cookieValue = null;
} else {
cookieStartAt = cookieValue.indexOf("=", cookieStartAt) + 1;
cookieEndAt = cookieValue.indexOf(";", cookieStartAt);
if (cookieEndAt == -1) {
cookieEndAt = cookieValue.length;
}
cookieValue = unescape(cookieValue.substring(cookieStartAt,
cookieEndAt));//解码latin-1
}
return cookieValue;

}



java中的API方式是cooke.setHttpOnly(boolean isHttpOnly),默认为false,若设置为true,则使用上面的script脚步是获取不到cookie的信息的。

在来说说secure,在java中API源码中这样解释该参数信息:

Indicates to the browser whether the cookie should only be sent using a

secure protocol, such as HTTPS or SSL.

The default value is false.

翻译:预示了浏览器中的cookie是否应该只使用一个安全协议,例如https或者ssl协议。默认值是false。

在java中的API方式的cookie.setSecure(boolean flag),默认是false,若设置为true。则想client发送的cookie,就不用已http协议的方式给服务器获取。也就是用http连接的方式:

  1.   当setSecure(true)时,浏览器端的cookie会不会传递到服务器端?
  2.   当setSecure(true)时,服务器端的cookie会不会传递到浏览器端?
  3. 答案:1)不会 ; 2)会

微信号:Fzuozj



喜爱读书,爱钻研技术,做自己。


    关注 做自己


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册

sso 相关文章