http协议是无状态协议,服务端不能从请求中判断用户的身份,用户怎么每次去找到自己对应的信息呢?
1. cookie
这种方式最简单,在用户第一次登陆成功某个网站A,网站A服务端就将你的用户信息(比如用户名,用户id,证件号等等)写入到cookie 对象中,然后再把这个cookie对象发送给对应的客户端,客户端就存下这个cookie,例如博客园的cookie如下
当cookie超时时间到了浏览器就会自动删除这个cookie,这个时候需要你重新登录一下, 然后服务器就会根据你的用户名和密码去数据库中查询一次,成功查询到就再一次将用户信息丢到cookie对象中,返回给客户端存起来,后续每次请求都带着这个cookie
这种方式的好处就是:用户的所有信息都存在客户端,服务端只有在数据库中存了一份,服务端压力很小;
坏处是显而易见,每次都要带上这个cookie这么多信息,一方面是传输效率问题,另一方面是安全问题,别人只要截获你的cookie,你的所有信息都一览无余;
还有一点就是有的客户端会禁用cookie...
2. session
在cookie的基础上优化了一下,因为不是有安全和效率问题吗,那么我们就把用户所有的信息都存到服务端,例如现在有这样的一个结构:Map<sessionId,Session<User>>
用户第一次登陆成功,就会生成一个唯一字符串sessionId,然后将sessionId和用户信息存到map中,最后就将这个sessionId丢到cookie返回给客户端,后续的客户端访问服务端只需要带着cookie,服务端就能从cookie中获取到这个sessionId,到Map里面去找,就可以找到用户信息了;
注意,不一定非要叫做sessionId这个名字啊,叫做aId,bId等等也行....看每个地方的要求
这种方式比较安全,而且效率也提高了,因为只需要多传一个字符串,但是服务端内存中存所有的用户信息,压力都给到了服务端
我们还从请求方式来比较cookie和session:
cookie的方式一般只能用户post请求,因为get请求的url有长度限制
session的方式只是get和post方式,get方式的话在url后面添加一个参数传sessionId就行了,即使客户端禁用了cookie,在服务端将sessionId传给了客户端之后,客户端想办法存起来下次请求的时候带过去就行了
3. session共享
上面说的是单体应用的实现方式,但是到了分布式环境下就会失效(很多东西在单机中使用是可以的,分布式环境下就没用了,比如数据库事务,锁),下图所示,会导致tomcat2需要用户重新登录
解决方案有两种:
1)hash一致性:在nginx中配置ip_hash,其实就是用过一定的算法对用户的ip处理,假如用户第一次访问的是tomcat1,那么只要用户ip不会变化,第二次该用户访问的还是tomcat1
2)引入中间件:这里以redis为例
4. jwt
上面的实现方式看着一大堆东西也是麻烦,又是传sessionId,又是引入redis,在分布式环境下有没有简单的方式啊!
jwt全称JSON Web Token,我们之前每次都是传的sessionId,这个字符串是没有实际意义的,只是起到了一个唯一标识的作用,那么有没有可能我们把它的语义化呢?就是想办法直接解析这个字符串,然后可以获取用户信息
下图所示,结构是不是一下子简单多了,可以看到只要我们每次请求都带上这个token,不管是单机环境,还是分布式环境都适用,而且服务端也不需要保存什么东西,客户端只需要保存一个token字符串就行了;
现在就比较关心的是jwt的那个算法和生成后的token字符串有什么特殊的要求!
token字符串的格式,分为三部分,用点进行连接:aaa.bbb.ccc
示例:
第一部分是Header:放入token的类型("JWT")和算法名称(比如:HMAC SHA256或者RSA等等),然后使用Base64对这个JSON编码就得到JWT的第一部分
第二部分是Payload:一般放入用户的不敏感信息,比如用户id,名称和角色等,即使被别人截获了也没啥用,然后使用Base64对这个JSON编码就得到JWT的第二部分
第三部分是Signature:准备一个只有你自己知道的密钥,加上第一部分的字符串aaa和第二部分的字符串,通过Header中声明的算法就生成了签名,也就得到了第三部分
将上面三部分通过点相连就组成了token,然后发到客户端,客户端只需要每次在请求头中放入这个token,后端通过密钥验证这个token的合法性,并且从Payload中获取用户不敏感的信息,进行后续处理
想看看简单的demo,可以看看这个老哥的博客 ,不过一般校验jwt是配置一个拦截器进行处理的
5. jwt的补充
其实仔细想了想,一般还有以下两个疑问
1)Token被盗了怎么办?
答: 在启用https的情况下,token被放在Header中还是比较安全的。另外Token的有效期不要设置过长。例如可以设置为1小时(微信公众号的网页开发的Token有效期为2小时)。
2)Token到期了如何处理?
答:理论上Token过期应该是跳到登录界面,但这样太不友好了。可以在后台根据Token的过期时间定期去请求新的Token。
可以看看以下两篇博客看看
应用JWT进行用户认证及Token的刷新
JWT生成token及过期处理方案
原文转载:http://www.shaoqun.com/a/571619.html
邮乐网购物商城:https://www.ikjzd.com/w/1776
weebly:https://www.ikjzd.com/w/2486
http协议是无状态协议,服务端不能从请求中判断用户的身份,用户怎么每次去找到自己对应的信息呢? 1.cookie 这种方式最简单,在用户第一次登陆成功某个网站A,网站A服务端就将你的用户信息(比如用户名,用户id,证件号等等)写入到cookie对象中,然后再把这个cookie对象发送给对应的客户端,客户端就存下这个cookie,例如博客园的cookie如下 当cookie超时时间到了浏览器
淘粉8:https://www.ikjzd.com/w/1725
c88:https://www.ikjzd.com/w/1017.html
拍拍购物:https://www.ikjzd.com/w/2205
亚马逊推新品、清库存的新功能,该功能能为店铺带来什么样效果呢?:https://www.ikjzd.com/home/125662
跨境电商成国内赚钱趋势,这4点告诉你成功者背后隐藏的秘密:https://www.ikjzd.com/home/19918
广告效果评估:30天的广告时间评估最全面:https://www.ikjzd.com/home/135486
没有评论:
发表评论