HTTP
HTTP是无状态(stateless)的网络协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说HTTP协议对于发送过的请求或响应都不做持久化处理。
为了实现保持状态功能,引入了Cookie技术来实现了HTTP的会话跟踪。
HTTP 缺点
- 通信使用明文可能会被窃听
- 不验证通信方的身份,因此有可能遭遇伪装
- 无法证明报文的完整性,所以有可能已遭篡改
为了解决这些缺点,HTTP上再加入加密处理和认证等机制。我们把添加了加密及认证机制的HTTP称为HTTPS(HTTP Secure)。
认证
认证时核对的信息
- 密码:只有本人才会知道的字符串信息。
- 动态令牌:仅限本人持有的设备内显示的一次性密码。
- 数值证书:仅限本人(终端)持有的信息。
- 生物认证:指纹和虹膜等本人的生理信息。
- IC卡等:仅限本人持有的信息。
HTTP/1.1 使用的认证方式
- BASIC 认证(基本认证)
- DIGEST 认证(摘要认证)
- SSL 客户端认证
- FormBase 认证(基于表单认证)
cookie-session 机制
当客户端请求服务端经过身份验证之后,服务端会生成并且保存身份信息相关的session数据,并且将对应sessionid写入cookie,通过响应传输给客户端,客户端将cookie保存在本地,以便第二次或以后的请求能够带上cookie中的sessionid去让服务端辨识该用户是属于哪个会话的(tomcat生成的sessionid叫做jsessionid),并且也会验证cookie字段中的logged_in字段,判断这个字段是因为,如果该用户是经过验证的,则这个字段的值肯定为(yes,true,1)这时,就无需重新认证身份,否则,需要重新进入身份认证流程。
Cookie
cookie就是服务端发放给客户端的一账通行证,并且通过这张通行证(cookie)来进行身份的辨识。本质上cookie是一小段文本信息,包含有如user_session/logged_in等可以标识用户以及可以表示用户的状态的一些字段。
cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。
cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。
Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。
Session
Session 生命周期
Session存储在服务器端,一般放置在服务器的内存中(为了高速存取),Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session,可调用request.getSession(true)强制生成Session。
Session 什么时候失效?
- 服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。Tomcat中Session的默认失效时间为20分钟。
- 调用Session的invalidate方法。
- 服务器重新启动。
关闭浏览器后,session 是否还存在?
session是基于cookie的一种会话技术, 数据存放存放在服务器端。客户端在cookie携带JSESSIONID(tomcat服务器生成),来访问服务端,获取对应JSESSIONID的session数据。
setAttribute 存放的值, 在浏览器关闭后,仍然存在!
为何关闭浏览器后,再次访问会觉得session失效了呢,这里的失效意思是session的数据丢失了?
其实这里session数据并没有丢失,只是关闭浏览器后,因为默认的cookie生命周期为浏览器的缓存,即关掉浏览器之后cookie就失效了,此时JSESSIONID也就没有了。再次访问后,服务器又生成一个新的JSESSIONID,此时request.getSession()通过JSESSIONID获取到的session就不是之前的session了。
Session 对浏览器的要求:
虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。
该Cookie为服务器自动生成的,它的maxAge属性一般为-1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。
注意:新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择"在新窗口中打开"时,子窗口便可以访问父窗口的Session。
如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?例如,绝大多数的手机浏览器都不支持Cookie。Java Web提供了另一种解决方案:URL地址重写。
URL地址重写是对客户端不支持Cookie的解决方案。URL地址重写的原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。HttpServletResponse类提供了encodeURL(String url)实现URL地址重写,该方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中。
注意:TOMCAT判断客户端浏览器是否支持Cookie的依据是请求中是否含有Cookie。尽管客户端可能会支持Cookie,但是由于第一次请求时不会携带任何Cookie(因为并无任何Cookie可以携带),URL地址重写后的地址中仍然会带有jsessionid。当第二次访问时服务器已经在浏览器中写入Cookie了,因此URL地址重写后的地址中就不会带有jsessionid了。
基于服务器验证方式暴露的一些问题
- Seesion:每次认证用户发起请求时,服务器需要去创建一个记录来存储信息。当越来越多的用户发请求时,内存的开销也会不断增加。
- 可扩展性:在服务端的内存中使用Seesion存储登录信息,伴随而来的是可扩展性问题。
- CORS(跨域资源共享):当我们需要让数据跨多台移动设备上使用时,跨域资源的共享会是一个让人头疼的问题。在使用Ajax抓取另一个域的资源,就可以会出现禁止请求的情况。
- CSRF(跨站请求伪造):用户在访问银行网站时,他们很容易受到跨站请求伪造的攻击,并且能够被利用其访问其他的网站。
Token
功能:
1.防止表单重复提交
2.用来作身份验证
token方式在app认证上用的比较普遍,App初始登录时,提交账号和密码数据给服务端,服务端根据定义的的策略生成一个token字符串,token字符串中可以包含用户信息、设备ID等信息以保证用户的唯一性。服务端并对token设置一定的期限。服务端把生成的token字符串传给客户端,客户端保存token字符串,并在接下来的请求中带上这个字符串。相对于在App本地token的安全性更高了。
App登录状态保持除了实现路径外还需要考虑服务端数据持久化问题、客户端防拷贝问题、拦截破解问题等,在使用中需要综合考虑。
token也称作令牌,由uid+time+sign[+固定参数]组成:
- uid: 用户唯一身份标识
- time: 当前时间的时间戳
- sign: 签名, 使用 hash/encrypt 压缩成定长的十六进制字符串,以防止第三方恶意拼接
- 固定参数(可选): 将一些常用的固定参数加入到 token 中是为了避免重复查库
以下几点特性会让你在程序中使用基于Token的身份验证:
- 无状态、可扩展
- 支持移动设备
- 跨程序调用
- 安全
由其组成可以看出, token 的认证方式类似于临时的证书签名, 并且是一种服务端无状态的认证方式, 非常适合于 REST API 的场景。 所谓无状态就是服务端并不会保存身份认证相关的数据。
token 只被保存在客户端 中的cookie 或 localstorage(数据库)。
因为用户的状态在服务端的内存中是不存储的,所以这是一种无状态的认证机制。
token的认证流程:
- 用户登录校验,校验成功后就返回Token给客户端。
- 客户端收到数据后保存在客户端,比如放在 Cookie 里或者 Local Storage 里。
- 客户端每次访问(请求数据)是携带Token到服务器端。
- 服务器端采用filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码。
缺点:
因为 token 一般都是 hash/encrypt 的字符串, 所以会额外附加 加密/解密 的性能开销,有些加密方式同样存在安全隐患。
token代码演示:https://blog.csdn.net/qq_37644380/article/details/74502821。
参考:
https://www.cnblogs.com/guangshan/p/4454328.html、https://www.jianshu.com/p/83f48ba6b1ff、https://www.cnblogs.com/liuwei0824/p/7699632.html、http://www.cnblogs.com/moyand/p/9047978.html(发展史)、https://www.jianshu.com/p/310d307e44c6。
关闭浏览器,session是否还存在:https://blog.csdn.net/xldmx/article/details/86532897。
token的认证流程:https://www.jianshu.com/p/310d307e44c6。
https://www.cnblogs.com/xzwblog/p/6834663.html(http认证、https简介)。