session,cookie 的身份认证那些事儿

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l00149133/article/details/78657248

我们知道,HTTP协议是一种无状态协议。也就是说,客户端和服务器端在一次请求结束后,两者的连接就会被关闭,当客户端再次请求服务器的时候,需要建立新的连接。

举个例子来说,客户端就是顾客,服务器端就是商人,请求就是顾客去找商人买东西。这个商人有个特点,只认东西不认人。所以对这个商人来说,没有所谓的“老主顾”,每次来买东西的人对他来说都是新面孔。

对于很多情况下来说,这样问题不大,因为买卖都是一锤子交易,记不记得也没什么差别。

但是现在商人为了让自己的生意更好,推出了一个VIP系统,只要在他这里买够100块钱的东西,以后买东西就能打八折。

这下商人不能只认东西不认人了,因为他要知道哪些用户是VIP,才能给这些用户打折。
所以商人自己有了个小本子(数据库),本子上记着VIP用户的姓名还有口令。

现在买东西的流程变成了流程A

顾客:老板我买个XXX
商人:你叫什么名字,口令是啥?
顾客:我叫张三,口令是天王盖地虎
商人:好,你等我查查小本子
...
商人:对,口令没问题,确认你是张三。你是VIP,可以八折卖给你/你不是VIP,只能原价卖给你

现在问题又来了,张三要买一堆东西,每次都要重复上面的流程A,每次都要问名字,对口令。商人跟张三都很头疼。
所以现在张三和商人商量了下,张三每次找商人的时候,都会自报家门,报出自己的身份(在cookie中携带身份信息)。
现在流程变成了流程B

顾客:老板我是张三啊,我前几天刚从你这里买了不少东西,这次我要买个XXX
商人:哦哦,是张三啊(自己翻了翻小本子发现张三是VIP),你是VIP,可以八折卖给你哟

这样流程简单了很多。
当然,自报家门也不是无限期的,商人指定张三自报家门的有效期是一个月(设置cookie的过期时间),如果超过了这个时限,张三来买东西还是要走流程A。

后来,某些有心人发现这个流程B是可以钻空子的,谁来了都可以冒充张三(cookie欺骗):

李四:老板我是张三啊(实际上是李四),我前几天刚从你这里买了不少东西,这次我要买个XXX
商人:哦哦,是张三啊(自己翻了翻小本子发现张三是VIP),你是VIP,可以八折卖给你哟

这尼玛就蛋疼了,谁来了都是VIP,商人为此亏了很多钱。
后来商人想了个办法:我们来对江湖黑话(使用token)吧,流程就变成了流程C

张三:洒家三儿啊寅时三刻D23131E4B1
商人:(“洒家三儿啊寅时三刻D23131E4B1”意思就是我是张三(uid),现在时间是2017121日(time),D23131E4B1是我们约定好的暗号(签名sign,加密算法得到,里面包括了某些动态参数,比如time,比如uid),他确实是张三)

李四不知道,还想来冒充张三:

李四:洒家三儿啊寅时三刻D23131E4B1
商人:(“洒家三儿啊寅时三刻D23131E4B1”意思就是我是张三(uid),现在时间是2017121日(time,我擦这个时间不对啊),D23131E4B1是我们约定好的暗号(签名sign,这个解密出来也不对。因为用到了time参与加密),他是个冒牌张三)

李四发现现在骗不了商人了,就潜心研究江湖黑话,后来终于破解了商人的黑话,明白了“洒家三儿啊寅时三刻D23131E4B1”的意思:

李四:洒家三儿啊子时四刻D23131E4B1
商人:(“洒家三儿啊子时四刻D23131E4B1”意思就是我是张三(uid),现在时间是2017123日(time,这个时间没问题),D23131E4B1是我们约定好的暗号(签名sign,这个解密出来也对。),他是张三)

商人过了一阵终于发现不对了,尼玛还是被伪造了啊。
然后他想了另外一个办法:当张三第一次来,走流程A的时候,商人告诉张三一条暗语,后面张三可以用这条暗语来认证自己的身份(客户端第一次请求时,服务器端生成session id,传给客户端,以后客户端每次请求,cookie里面都带着session id)。
当然,这条暗语也是有有效期的,过期后张三还是要走流程A。
商人为了记录暗语,又准备了一张A4纸(数据库,但是要比用户数据库小的多,查起来很快)来记录暗语和对应的顾客(起码不用翻厚厚的小本子了)
现在的流程变成了:

//第一次张三来的时候
顾客:老板我买个XXX
商人:你叫什么名字,口令是啥?
顾客:我叫张三,口令是天王盖地虎
商人:好,你等我查查小本子
...
商人:对,口令没问题,确认你是张三。你是VIP,可以八折卖给你。另外我告诉你一条暗语“芭芭拉小魔仙”,一个月以内你来,都可以报暗语来认证你的身份,暗语不要告诉别人哟

然后:

//张三第二次来
张三:我是张三,芭芭拉小魔仙,我要买个XXX
商人:你等我看看A4纸。。。
商人:你果然是张三!

但是这样也会有几个问题:
问题一:
商人的生意越做越好,他忙不过来,就找了几个伙计(服务器集群)帮忙一起卖东西,现在问题来了:

//第一次张三来的时候
顾客:老板我买个XXX
伙计A:你叫什么名字,口令是啥?
顾客:我叫张三,口令是天王盖地虎
伙计A:好,你等我查查小本子
...
伙计A:对,口令没问题,确认你是张三。你是VIP,可以八折卖给你。另外我告诉你一条暗语“芭芭拉小魔仙”,一个月以内你来,都可以报暗语来认证你的身份,暗语不要告诉别人哟

然后:

//张三第二次来
张三:我是张三,芭芭拉小魔仙,我要买个XXX
伙计B:你等我看看A4纸。。。
伙计B:不认识你啊,神经病啊!

可以看到,伙计A(服务器A)告诉了张三暗语(session id),但是伙计B(服务器B)并不知道这个暗语。而张三来买东西,哪个伙计接待是不确定的(每个伙计都有自己的一张A4纸)!
这个问题引申开了就比较麻烦了,涉及到集群session的问题,简单来说有3种处理办法:
session保持(这个顾客之前是哪个伙计接待的,后面还是哪个伙计接待。但是这样就不是真的“负载均衡”了)
session复制(所有伙计都要把别的伙计的session复制一份,以保持一致)
session共享(所有伙计共用一张A4纸)

问题二
商人的生意越来越好,买东西的人络绎不绝,A4纸不够用了,只能再加几张,这样一搞,其实速度没怎么增加啊。
只能想个别的办法啊。。。
对了,用脑子(内存,使用redis)来记,这样就不用查了,但是为了提升我的记忆力,我得先喝点鳖精(增加内存)。。。

问题三
过了一阵商人发现,有些顾客脾气比较大,不屑于去记什么暗号(禁止cookie)。这导致商人的暗语发出去了,下次这个顾客来还是不会给商人暗语,只能一次又一次的走流程A。
没办法,商人只能想了这么个办法:

商人:这位主顾啊,你看你这次买了不少东西,你买下一件东西的时候,按照本店规定要这么说:“我是张三,我要买个XXX;芭芭拉小魔仙”(url重写,类似http://test.com/shop;jsessionid=00A321DB1)

问题四
李四还是很不甘心啊,虽然上次破解了加密解密,但是现在因为暗语,又不能伪装VIP了。
思来想去,李四想了一个很简单的办法—-偷听
每次张三去买东西的时候,李四都在旁边偷听,终于某次被他听清楚暗语了,然后:

李四:我是张三,芭芭拉小魔仙,我要买个XXX
商人:你等我看看A4纸。。。
商人:你果然是张三!

商人过了一段时间,发现还是不行啊,又尼玛被伪造了。
思来想去,只能祭出最后的大招了!

李四:我是张三,芭芭拉小魔仙,我要买个XXX
商人:你等我看看A4纸。。。
商人:你果然是张三!你是VIP,买东西可以打八折
李四:对对对,我是VIP,这是80块钱,原价100块钱的XXX我来一个~
商人:(好,终于到了最终付款阶段了,这么关键的步骤,我需要再次确认一遍!)
商人:姓名!口令!
李四:。。。。。。。

所以说,我们允许你通过cookie来获取一些非重要的信息,但是对于一些重要的请求,我们还是要重新确认一遍身份!

猜你喜欢

转载自blog.csdn.net/l00149133/article/details/78657248
今日推荐