鉴权授权
众所周知,web server是无状态的,也就是说服务器不知道用户在最后一次请求中做了什么,请求之间是相互独立的。客户信息仅来自每个请求携带的或由服务器本身保存的公共信息,并且可以被所有请求使用。因此,为了跟踪用户请求的状态信息,比如网购的购物车历史,Cookie应运而生。
当服务器响应客户端的请求时,它会向客户端推送一个Cookie。这个Cookie记录了服务器上的一些信息。客户端在后续请求中携带这个Cookie,服务器可以根据这个Cookie判断请求的上下文。
Cookie的出现是从无国籍状态过渡到有国家状态的一种手段。
以登录为例,用户输入帐户名和密码,向服务器发送请求。服务器生成一个Cookie并发送给浏览器。浏览器将Cookie以k-v的形式保存在某个目录下的文本文件中,下次请求同一个网站时会将Cookie发送给服务器。服务器验证接收到的Cookie是否与服务器的Cookie一致;否则,验证失败。这是最初的想法。
img src=' https://P6 . toutiaoimg.com/large/PGC-image/48e 7b 24 ea 95 f 4 E0 CB 8d 940 DC 05 feb 1 EC '/
存储在浏览器中的Cookie的位置如下图所示。
img src=' https://p26 . toutiaoimg.com/large/PGC-image/b 35 b 701d 7 b 454 ada 95 a 49 a 36d 0026 a F9 '/
Cookie的原理决定了他具有以下特征:
在存储客户端,可以随意篡改,不安全。
它的内容会和http交互传输,会影响性能,所以Cookie能存储的数据不能太大,最多4kb。
一个浏览器只能为一个网站存储不超过20个cookie,而浏览器一般只允许300个cookie。
移动对Cookie支持不友好。
一般来说,存储的是纯文本,对象在存储之前需要序列化,解析需要反序列化。
还是以登录Cookie为例。例如,现在有两个二级域名,http://a.xxx.com(域名A)和3358b.xxx.com(域名B)。那么域名A的登录Cookie可以在域名B下使用吗?
默认情况下,域名A的服务主机中生成的Cookie只能由域名A的服务器获取,其他域名无法获取这个Cookie,只能是主机Cookie。
但是,服务器可以显式声明Cookie的域来定义它的域。比如域名A的登录Cookie的域设置为http://xxx.com(他们共同的顶级域名),path设置为'/',Set-Cookie:name=value;domain=xxx.comPath='/',那么域名B就可以读了。
在新规范rfc6265中,domain的值将忽略任何前导点,即子域中可以使用**xxx.com**和* * XXX.com * *。SSO(单点登录)也是根据这个原理实现的。
例如,现在有两个域名,a.b.e.f.com.cn(域名1)和c.d.e.f.com.cn(域名2)。域名2想读取域名1的Cookie。域名1可以声明哪些域?答案是e.ffcom.cn或者. f.com.cn,浏览器不能接受以domian为.com.cn的cookie,因为如果cookie域名可以设置为后缀的话,那就是峡谷大战了。
如果域名1设置了Set-Coo
kie:mykey=myvalue1;domain=e.f.com.cn;path=’/’
域名 2 设置Set-Cookie:mykey=myvalue2;domain=e.f.com.cn;path=’/’
那该域下 mykey 的值会被覆盖为 myvalue2,很好理解,同一个域下,Cookie 的 mykey 是唯一的。通常,我们要通过设置正确的 domain 和 path,减少不必要的数据传输,节省带宽。
随着交互式 Web 使用的兴起,Cookie 大小的限制以及浏览器对存储 Cookie 的数量限制,我们一定需要更强大的空间来储存大量的用户信息,比如我们这个网站是谁登录了,谁的购物车里加入了商品等等,服务器要保存千万甚至更多的用户的信息,Cookie 显然是不行的。那怎么办呢?
那将用户信息存储在哪呢?能否直接存在服务器中?
如果存在服务器中,1、这对服务器说是一个巨大的开销,严重的限制了服务器的扩展能力。2、假设 web 服务器做了负载均衡,用户 user1 通过机器 A 登入该系统,那么下一个请求如果被转发到另一台机器 B 上,机器 B 上是没有存该用户信息的,所以也找不到 sessionId,因此 sessionId 不应该存储在服务器上。这个时候redis/Memcached便出来解决该问题了,可以简单的理解它们为一个缓存数据库。
当我们把 sessionId 集中存储到一个独立的缓存服务器上,所有的机器根据 sessionId 到这个缓存系统里去获取用户信息和认证。那么问题就迎刃而解了。
根据其工作原理,你有没有发现这个方式会存在一个什么样的问题?那就是增加了单点登录失败的可能性,如果负责 session 的机器挂了, 那整个登录也就挂了。但是一般在项目里,负责 session 的机器也是有多台机器的集群进行负载均衡,增加可靠性。
思考:
假如服务器重启的话,用户信息会丢失吗?
Redis 等缓存服务器也是有个集群的,假设某一台服务重启了,会从其他运行的服务器中查找用户信息,那假设真的某一次所有服务器全都崩溃了,怎么办呢?大概的应对策略就是,存储在内存中的用户信息会定期刷到主机硬盘中以持久化数据,即便丢失,也只会丢失重启的那几分钟内的用户数据。
Cookie-session 局限性
依赖 Cookie,用户可以在浏览器端禁用 Cookie
不支持跨端兼容 app 等
业务系统不停的请求缓存服务器查找用户信息,使得内存开销增加,服务器压力过大
服务器是有状态的,如果是没有缓存服务器的方式,扩容就非常困难,需要在多台服务器中疯狂复制 sessionId
存在单点登录失败的可能性
单点登录(Single Sign On),简称为 SSO。随着企业的发展,一个大型系统里可能包含 n 多子系统,用户在操作不同的系统时,需要多次登录,很麻烦,单点登录就是用来解决这个问题的,在多个使用系统中,只需要登录一次,就可以访问其他相互信任的使用系统。
之前我们说过,单点登录是基于 cookie 同顶域共享的,那按照不同的情况可分为以下 3 种类型。
同一个站点下;
系统在相同的顶级域名下;
各子系统属于不同的顶级域名
一般情况下一个企业有一个顶级域名,前面讲过了,同一个站点和相同顶级域下的单点登录是利用了 Cookie 顶域共享的特性,相信大家已经明白这个流程,不再赘述。但如果是不同域呢?不同域之间 Cookie 是不共享的,怎么办?
这里我们就要说一说 CAS(中央认证服务 )流程了,这个流程是单点登录的标准流程。它借助一个单独的系统专门做认证用,以下成为SSO系统。
它的流程其实跟 Cookie-session 模式是一样的,单点登录等于说是每个子系统都拥有一套完整的 Cookie-session 模式,再加上一套 Cookie-session 模式的 SSO 系统。
用户访问系统 a,需登录的时候跳到 SSO 系统,在 SSO 系统里通过账号密码认证之后,SSO 的服务器端保存 session,,并生成一个 sessionId 返回给 SSO 的浏览器端,浏览器端写入 SSO 域下的 Cookie,并生成一个生成一个 ST,携带该 ST 传入系统 a,系统 a 用这个 ST 请求 SSO 系统做校验,校验成功后,系统 a 的服务器端将登录状态写入 session 并种下系统 a 域下的 Cookie。之后系统 a 再做登录验证的时候,就是同域下的认证了。
这时,用户访问系统 b,当跳到 SSO 里准备登录的时候发现 SSO 已经登录了,那 SSO 生成一个 ST,携带该 ST 传入系统 b,系统 b 用这个 ST 请求 SSO 系统做校验,校验成功后,系统 b 的服务器端将登录状态写入 session 并设置系统 b 域下的 Cookie。可以看得出,在这个流程里系统 b 就不需要再走登录了。
关于“跳到 SSO 里准备登录的时候发现 SSO 已经登录了”,这个是怎么做的呢,这就涉及 Oauth2 授权机制了,在这里就不展开讲,简单提个思路,就是在系统 b 向 SSO 系统跳转的时候让它从系统 a 跳转,携带系统 a 的会话信息跳到 SSO,再通过重定向回系统 b。
关于 Oauth2,可移步阮一峰 的《OAuth 2.0 的四种方式》。
我们已经分析过 Cookie-session 的局限性了,还有没有更彻底的解决办法呢?既然 SSO 认证系统的存在会增加单点失败的可能性,那我们是不是索性不要它?这就是去中心化的思路,即省去用来存储和校验用户信息的缓存服务器,以另外的方式在各自系统中进行校验。实现方式简单来说,就是把 session 的信息全部加密到 Cookie 里,发送给浏览器端,用 cpu 的计算能力来换取空间。
服务端不保存 sessionId,用户登录系统后,服务器给他下发一个令牌(token),下一次用户再次通过 Http 请求访问服务器的时候, 把这个 token 通过 Http header 或者 url 带过来进行校验。为了防止别人伪造,我们可以把数据加上一个只有自己才知道的密钥,做一个签名,把数据和这个签名一起作为 token 发送过去。这样我们就不用保存 token 了,因为发送给用户的令牌里,已经包含了用户信息。当用户再次请求过来的时候我用同样的算法和密钥对这个 token 中的数据进行加密,如果加密后的结果和 token 中的签名一致,那我们就可以进行鉴权,并且也能从中取得用户信息。
对于服务端来说,这样只负责生成 token , 然后验证 token ,不再需要额外的缓存服务器存储大量的 session,当面对访问量增加的情况,我们只需要针对访问需求大的服务器进行扩容就好了,比扩充整个用户中心的服务器更节省。
假如有人篡改了用户信息,但是由于密钥是不知道的,所以 token 中的签名和被篡改后客户端计算出来的签名肯定是不一致的,也会认证失败,所以不必担心安全问题。
关于 token 的时效性,是这样做的,首次登陆根据账号密码生成一个 token,之后的每次请求,服务端更新时间戳发送一个新的 token,客户端替换掉原来的 token。
jwt 模式的退出登录实际上是假的登录失效,因为只是浏览器端清除 token 形成的假象,假如用之前的 token 只要没过期仍然能够登陆成功
安全性依赖密钥,一旦密钥暴露完蛋
加密生成的数据比较长,相对来说占用了更大的流量
不依赖 Cookie,可跨端跨程序使用,支持移动设备
相对于没有单点登录的 cookie-session 模式来说非常好扩展
服务器保持了无状态特性,不需要将用户信息存在服务器或 Session 中
对于单点登录需要不停的向 SSO 站点发送验证请求的模式节省了大量请求
相关问答:
版权转让和授权的区别是什么
1、版权转让和授权主要是权利归属的区别,授权书并不转移著作权主体,仅是允许他人合法使用的授权协议。版权转让书是著作权主体的变更,原著作权人在签署协议后不在享有相关权利。转让一般是较长时间的,而授权使用一般仅限于较短时间,转让的付酬较高,而授权使用的付酬相对低一些。2、【法律依据】3、...
分权与授权之间的关系
分权与授权之间的关系:1、权力范围不同。授权授予的权力范围不限,只要是完成任务所必需的权力都可以授予,此案中张峰签署报销单的权力,孙文指挥下属完成任务的权力都属于授权。而分权只是将决策指挥权分散。2、时间长短不同。授权具有短期性,任务完成即收回,而分权则是长期性的,一般不出问题不收回。
授权与分权的联系与区别
分权与授权之间的关系:1、权力范围不同。授权授予的权力范围不限,只要是完成任务所必需的权力都可以授予,此案中张峰签署报销单的权力,孙文指挥下属完成任务的权力都属于授权。而分权只是将决策指挥权分散。2、时间长短不同。授权具有短期性,任务完成即收回,而分权则是长期性的,一般不出问题不收回。
所谓授权是指什么
法律分析:“授权”指把权力委托给他人或机构代为执行。法律依据:《中华人民共和国民法典》第一百六十五条 委托代理授权采用书面形式的,授权委托书应当载明代理人的姓名或者名称、代理事项、权限和期限,并由被代理人签名或者盖章。第九百二十五条 受托人以自己的名义,在委托人的授权范围内与第三人...
授权的三种形式
1、根据在授权时所凭借的媒介的不同,我们可以将领导授权分为口头授权与书面授权。2、根据授权的规范性程度的不同,我们可将领导授权分为正式授权与非正式授权。3、根据工作内容的重要性程度、上下级的水平与能力等综合情况,我们可将领导授权分为充分授权、不充分授权、制约授权和弹性授权等形式。法律...
授权与分权的区别
对工作情况和程序进行总结、评价,以便改进管理工作。法律依据《中华人民共和国民法典》第一百六十五条 委托代理授权采用书面形式的,授权委托书应当载明代理人的姓名或者名称、代理事项、权限和期限,并由被代理人签名或者盖章。第三百一十二条 所有权人或者其他权利人有权追回遗失物。该遗失物通过转让...
授权的十一条原则
·用钱之权 ·用人之权 ·做事之权授权中的“用钱之权”需要注意的同类有五种,即考虑预算内或预算外账目的种类、金额的大小、正式或非正式的授予形式及下属的级别层次。授权中的“用人之权”包含两个方面:其一,决定某个时间内要增加哪些人的权力;其二,在这些增用的人中,选用哪些特定人员的权力。
授权应遵循的原则
4、授权有限原则。授权者不可将自身不具有的职权或应当自己掌握的重大职权授予下级。5、授权监督原则。授权者对被授权者在执行授权事务时进行监督,如被授权者违反授权范围,触犯法律、法令时,授权者有权纠正。法律依据:《中华人民共和国行政诉讼法》 第二十五条 行政行为的相对人以及其他与行政行为有利害...
专利权授权后,专利权人可以享有哪些权利?
申请人的发明创造被授予专利权后:专利权人有如下权利:1.自行实施其专利的权利(需不侵犯其他专利权);2.转让专利权的权利;3.许可他人实施其专利的权利;4.禁止他人未经许可实施其专利的权利;5.在专利权受到侵犯时请求保护的权利;6.在产品上标明专利权的权利。自申请日至授权日,享有临时保护。
著作权转让和授权是一回事吗
是两回事。转让只是把著作权卖掉,之后著作权人就失去了全部的权利。授权是指著作权人把权利授权给他人,自己仍保留著作权的所有权。著作权的转让,是指著作权作为一项财产权,包括复制权、发行权、展览权、公开表演权、播放权、改编权、翻译权、汇编权、以及整理权和注释权等或者是其中的任何一项或几项...
西苗愈通: 鉴权(authentication)是指验证用户是否拥有访问系统的权利.传统的鉴权是通过密码来验证的.这种方式的前提是,每个获得密码的用户都已经被授权.在建立用户时,就为此用户分配一个密码,用户的密码可以由管理员指定,也可以由用户自行申请.
盐山县18358569367: 天弘基金的鉴权是什么 - ?
西苗愈通: 天弘基金的鉴权(authentication)是指验证用户是否拥有访问天弘基金系统的权利.传统的鉴权是通过密码来验证的.这种方式的前提是,每个获得密码的用户都已经被授权.在建立用户时,就为此用户分配一个密码,用户的密码可以由管理员指定,也可以由用户自行申请.这种方式的弱点十分明显:一旦密码被偷或用户遗失密码,情况就会十分麻烦,需要管理员对用户密码进行重新修改,而修改密码之前还要人工验证用户的合法身份.为了克服这种鉴权方式的缺点,需要一个更加可靠的鉴权方式.目前的主流鉴权方式是利用认证授权来验证数字签名的正确与否.
盐山县18358569367: 蓝牙鉴权设置是什么? - ?
西苗愈通: 你好,鉴权应该是蓝牙配对的时候需要输入相同的口令,如果没有鉴权或者鉴权关闭了的话在配对的时候就不需要输入密码的.应该是这样的.呵呵,现在我正在做任务,如果答案对你有帮助的话请及时采纳哦,谢谢拉.
盐山县18358569367: 什么叫做鉴权 - ?
西苗愈通: 用户鉴权用于用户登陆到DSMP或使用数据业务的时候,业务网关或Portal发送此消息到DSMP,对该用户使用数据业务的合法性和有效性(状态是否为激活)进行检查.根据业务网关和Portal中用户进入方式的不同,提供四种方式的用户鉴权...
盐山县18358569367: CDMA中的AN/AAA和A - key是什么意思 - ?
西苗愈通: AN指的是access network ,AAA分别是 Authentication,Accounting,Authorization的缩写,指的是接入网鉴权,授权和计费 A-key是发布给CDMA终端的一个鉴权密钥,分别存储于SIM卡和鉴权中心
盐山县18358569367: "鉴权失败“是怎么回事,如何处理 - ?
西苗愈通: 春天我来了 wrote: 下载完客户端,打开SDEDU.EXE,就出现”鉴权失败“的对话框,再登录,出现我所在的学校,但学籍信息不能同步,提示“鉴权失败' 经过两节课的试验,鉴权失败的问题终于解决了,方法如下: 一,登录平台,系统...
盐山县18358569367: 银行卡一步一权什么意思??
西苗愈通: 鉴权,是指验证用户是否拥有访问系统的权利. 传统的鉴权是通过密码来验证的. 这种方式的前提是,每个获得密码的用户都已经被授权. 在建立用户时,就为此用户分配一个密码,用户的密码可以由管理员指定,也可以由用户自行申请. 这种方式的弱点十分明显:一旦密码被偷或用户遗失密码,情况就会十分麻烦,需要管理员对用户密码进行重新修改,而修改密码之前还要人工验证用户的合法身份.
盐山县18358569367: 信用卡刷卡时显示请银行卡鉴权 - ?
西苗愈通: 最近磁条卡被盗刷,调单的事件多,所以凡是磁条卡的大额交易,都会出现交易失败94,请银行卡鉴权.这是支付公司保护商户利益的一个手段.因为磁条卡容易被复制,所以就容易被盗刷,芯片卡就不存在这种问题.调单,就是有的持卡人卡...
盐山县18358569367: 手机和电脑蓝牙连接鉴权码是什么 - ?
西苗愈通: 授权码是被连接蓝牙设备上输入的数字,输入四位任意数字后,在连接蓝牙设备上再输入就可以通过授权连接.