会话管理方式
http是无状态的,这就意味着客户端即使第一次请求已经验证了身份,但是第二次请求的时候服务器仅通过http连接并不能知道是那个用户。但是我们是需要状态管理的,比如用户登录了才能做一些其它操作,这就需要我们进行会话管理。
这里主要讲两种管理方式
- 基于session的管理方式
- 基于ticket管理方式
1. 基于session的方法
- 客户端送第一次请求后,服务端在服务器创建session信息,并将sessionid传送给浏览器
第一次请求
第一请求并没有带cookie信息,服务器返回set-cookie字段,并带有sessionid(laralve_session)
- 客户端再次请求会通过cookie带着这个sessionid
再次请求
因为上次的响应有set-cookie字段,将sessionid储存到cookie中,现在请求已经带着cookie字段,里面包含sessionid
3.这样我们就可以通过这个sessionid进行用户状态管理。
实际上上面的session并不具备会话管理功能,但是我们可以将我们的用户状态放到session对象里面,并存储在服务端。用户登录成功后,我们将登录凭证存储在session对象中,这样服务端在收到sessionid的时候就可以判断对应的session对象是否含有登录凭证,如果有则证明登录成功。
问题:
- session信息需要存储在服务端,信息过多会占用较多内存
- 服务器集群部署,多台服务器之间session信息不共享
- cookie要存储在域名下,如果同属于一级域名下比较好解决,但是如果不同域就有些麻烦,不能跨域,这就需要针对性解决
在实际部署中我们可能会使用redis存储,这样可以减轻服务器压力,也能解决服务器session共享问题
2. 基于ticket的方式
用户登录信息合法,服务端产生ticket信息,响应中将ticket信息传递给客户端,客户端并将ticket信息存储在客户端,以后每次请求的时候带着ticket信息,服务端收到每次请求后都验证ticket是否存在并且合法有效,来确认用户是否登录
- 用户使用用户名密码登录,服务端验证服务名密码是否正确,如果正确则创建登录凭证,这个登录凭证可能包含着用户id,过期时间等。
- 将登录凭证+签名+其它加密处理,然后将加密处理的字符串存储到客户端。
- 客户端发送请求后,服务端每次检测是否有此ticket信息,如果有则解密处理,查看签名是否正确,是否过期等等,如果都合法则说明用户登录有效。
问题:
- 储存的用户信息过多,导致ticket过大,如果使用cookie存储的话,cookie大小有限制,加密字符串过长的话会引发其他问题
- 每次请求都要带着ticket信息,ticket信息又比较大,降低访问性能
- 过期自动刷新问题
实际上在客户端ticket字符串不一定非要存储在cookie中,我们还可以存储在localstorage,sessionstroage等的地方。只要我们每次请求的时候取得这个ticket信息并且让服务端知道就可以表明身份。
关于这种方式,可以符合现成的标准JWT,这样就比较规范了,有兴趣的可以了解。
3. 总结
- 比较下上面两种方式,基于session的方式将用户凭证保存在服务端,基于ticket的方式保存在客户端。
- 只要不泄露以上的两种会话机制还是比较安全的,各有各的应用场景,根据自身情况来处理
- 以上都没有避免sessionid,ticket(加密字符串)的泄露问题,一旦泄露别人就可以冒充我们,做一些不可告人的事情。关于传输过程中的窃取可以使用https来避免,在客户端的凭证窃取需要我们自己注意了,比如laravel就使用csrf_token来避免CSRF攻击。
参考资料
http://www.cnblogs.com/lyzg/p/6067766.html
原文地址:https://www.cnblogs.com/redirect/p/8658613.html