Session、cookie、Token的关系

HTTP协议是无状态的服务,不会记录客户端的身份等基本信息,比如打开浏览器,访问一个网页50次和访问1次对于服务器来说没有区别。

一、Session、Cookie的作用
Session是客户端与服务器通讯会话跟踪的一门技术,可以使服务器与客户端保证整个通讯的会话基本信息。

客户端在第一次访问服务器的时候,服务端会响应一个sessionId,并且将它存入到客户端本地的cookie中,在之后的访问会将cookie中的sessionId放入到请求头中去访问服务器,如果服务器通过这个sessionId没有找到对应的数据,那么服务器会创建一个新的sessionId并且响应给客户端。

二、分布式Session存在的问题?
假设第一次访问服务A生成一个sessionId并且存入到cookie中,第二次却访问服务B(可能需要调用到服务器B上的某个模块),客户端会在cookie读取sessionId加入到请求头中,如果在服务器B通过sessionId没有找到对应的数据那么慢它创建一个新的sessionId并且将它返回给客户端,这样并并不能共享我们的sessionId。

解决方案:

(1)基于Cookie的Session共享

在大型网站中比较普遍使用。原理是将全站用户的Session信息加密、序列化后以Cookie的方式,统一存储到根域名下(比如:.host.com),利用浏览器访问该根域名下的所有二级域名站点时,会传递与之域名对应的所有Cookie内容的特性,从而实现客户端Cookie的Session在多服务器间的共享访问。

优点:

无需额外的服务器资源;
缺点:

由于受HTTP协议头信息长度的限制,仅能够存储小部分的用户信息,同时Cookie化的Session内容需要进行安全加解密(比如:采用DES、RSA等进行明文加解密;再由MD5、SHA-1等算法进行防伪认证), 此外它也会占用一定的带宽资源,因为浏览器会在请求当前域名下任何资源时将本地Cookie附加在HTTP头部中传递给服务器。
(2) 基于Redis的Session共享

该方案使用Redis来存储用户 的登录状态,Redis服务器也存在多做存储数据的淘汰策略,与Session的过期机制非常类似。目前是互联网公司最为广泛使用的方案之一。实现原理其实就是把每次用户的请求时候生成的sessionId存储在Redis上,然后在基于Redis的特性进行设置一个失效时间的机制,这样就能保证客户端在Redis中的session失效时间内,都不需要进行再次登录。

优点:

能适应于负载均衡策略;
服务器重启或宕机不会造成session丢失;
安全性较高;
扩展能力强;
适合集群数量大的使用;
缺点:

对应用有侵入,应加强相关配置;
增加一次网络开销,用户体验降低;
序列化和反序列化消耗CPU性能;
(3) 基于Nginx的ip_hash负载均衡

其实就是对请求过来的IP地址对N台服务器进行取模,然后就会把客户端的请求通过Nginx的反向代理给分发到对应的服务器上。(这里会把可用的服务器放到一个数组中,如果取模得到的结果是idx,就把请求分到服务器数组重点的下标为idx的服务器上)

优点:

配置简单,对应用无侵入性,不需要修改代码;
只要hash属性是均匀的,对台web-server的负载是均衡的;
便于服务器水平扩展;
便于服务器水平扩展;
安全性较高;
缺点:

服务器重启会造成部分session丢失;
水平扩展过程中也会造成部分session丢失;
存在单点负载过高的风险;
(4) 基于Tomcat的Session共享

当客户端请求的时候,把所产生的sessionId复制到系统中所有的服务器中,这样就能保证当请求的时候从服务器A可能调用到服务器B上的模块时,也能保证服务B也有该用户的sessionId,这样就不会再次让客户端进行再次登录操作。

三、Token的引入
Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。
Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
    了解了Token的意义后,我们就更明确的知道为什么要用它了。

    (1)如何使用Token?

1、用设备号/设备mac地址作为Token(推荐)

    客户端:客户端在登录的时候获取设备的设备号/mac地址,并将其作为参数传递到服务端。

    服务端:服务端接收到该参数后,便用一个变量来接收同时将其作为Token保存在数据库,并将该Token设置到session中,客户端每次请求的时候都要统一拦截,并将客户端传递的token和服务器端session中的token进行对比,如果相同则放行,不同则拒绝。

分析:此刻客户端和服务器端就统一了一个唯一的标识Token,而且保证了每一个设备拥有了一个唯一的会话。该方法的缺点是客户端需要带设备号/mac地址作为参数传递,而且服务器端还需要保存;优点是客户端不需重新登录,只要登录一次以后一直可以使用,至于超时的问题是有服务器这边来处理,如何处理?若服务器的Token超时后,服务器只需将客户端传递的Token向数据库中查询,同时并赋值给变量Token,如此,Token的超时又重新计时。

2、用session值作为Token

    客户端:客户端只需携带用户名和密码登陆即可。

    服务端端:服务端接收到用户名和密码后并判断,如果正确了就将本地获取sessionID作为Token返回给客户端,客户端以后只需带上请求数据即可。

分析:这种方式使用的好处是方便,不用存储数据,但是缺点就是当session过期后,客户端必须重新登录才能进行访问数据。
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值