三种常见的Web会话管理方式
要了解三种常见的会话管理方式之前,先要知道为什么会出现这些方式?做开发的童鞋应该都知道http是没有状态的,请求完成链接就断开了,下次再请求的时候又不知道是谁发的。对于我们的网页应用来说这显然是很致命的。这时我们就需要使用会话管理
来让服务端精准的判断这个请求是哪个用户发送的,以进行往后的一系列操作。
1、cookie
客户端发起登录请求,服务端验证登录信息,如果登录成功就创建一个登录凭证(比如userid)写到cookie当中,并且设置一个有效期。
一般登录凭证都会做加密处理,以防被人截取。
客户端登录成功之后,再发起请求的时候就会携带上这个凭证。服务端拿到凭证之后会进行验证,成功之后用凭证的过期时间和当前时间做比较,如过已经过期则需要重新登录。如果没有过期就继续后续操作。
从网上找了一个图片以便理解整个流程:
cookie.png这种方式好的一点是,不需要服务端进行太多的管理操作,只要创建验证等操作。在访问量大的时候有效的减轻了服务端的压力。而且就算是多服务器也没事,因为状态是在cookie中,在哪个服务器都可以拿到。
当然有利就有弊:
-
cookie是有大小限制的,不能存放太多数据
-
每次请求都传送cookie,增加了请求的数量,对性能会有些影响
-
因为cookie是按照域名存的,所以存在跨域问题
2、session
Session与Cookie在本质上没有区别,都是针对HTTP协议的局限性而提出的一种保持客户端和服务器间保持会话连接状态的机制。但是它是将会话状态存在服务器端。
用户在第一次访问的时候,服务器端就会创建一个session对象代表一个会话过程,用来存放数据。并且为每一个session分配一个唯一的sessionId,然后这里还是要用到cookie,通过cookie吧sessionId传递到客户端浏览器,再次访问时就会携带这个sessionId,服务端就可以通过它去查找对应的session对象。
session一般会设定一个失效的时间,如果用户在这段时间内登录了,那么服务端就会把有效期再延长。如果有效期内没有登录,那么就销毁过期的session,再创建新的session返回给客户端。
session.png它的优点是比较安全,因为信息全部存在服务器端,与客户端之间只传递一个sessionId串。
当然,信息存在服务器端也有很多缺点:
-
访问量大时,会占用较多的服务器内存
-
因为session是有某个服务器创建的,当应用采用集群部署的时候,多台服务器之间怎么共享session。
-
既然涉及到多态服务器,就要也要考虑到cookie跨域问题。
面对这些问题,我们也有一些对应解决办法:比如共享session这个问题,我们可以使用redis这种中间服务器来管理对session的操作,既减轻了服务器的压力又实现了session共享。然后就只需要解决cookie跨域问题了。
3、token
以上两种方式,在web应用中没有什么问题,但是如果是在native app上,因为要用到cookie,所以并不好管理。这时token是个不错的选择。
它和cookie的方式区别不大,但是token不写在cookie里。当用户登录成功之后服务端会将token传递给客户端,客户端将token存在本地之后,以后每次请求的时候主动添加到http header或者url后面。听到每次主动添加感觉貌似有点麻烦,但是大家都知道,只要把方法封装一下并没有什么。
token.png和cookie一样会有token刷新的问题,同样,如果在有效期内登录就把失效时间延长。然后再返给客户端。客户端检测到有新的token之后就把旧的替换掉。