应用鉴权就是当一个用户进入APP时,我们需要判断他所拥有的权利,根据权力来判断他所能进行的一个行为,最为常见的就是购物网站的登录以及购物支付等 *** 作。
Http的请求是无状态的,就是说在一个Http请求中的请求方和响应方都是无法维护状态,是一次性的,所以我们就不知道请求前后都发生了什么。所以我们需要标记的功能,而浏览器的sessionStorage,localStorage,全局变量等限制太多,就有了cookie,session,token等鉴权的 *** 作。
cookie也是一种前端存储的方式,但是他和sessionStorage,localStorage等本地存储的不同在于,浏览器向服务端发起请求的时候,cooike是自动传过去的,可以做到前端无感知,出错的概率更低
过程:
1.浏览器向服务器发起请求并传送数据,由服务器接收数据然后设置cooike放进响应头(Set-Cookie),浏览器接收到响应之后就会自动存储进cookie
2.在之后的每一次请求中浏览器都会自动的在请求头之中设置cookie字段,发送给服务端
配置:
1.Domain/Path
cookie 是要限制空间范围的,通过 Domain(域)/ Path(路径)两级。
2.Expires / Max-Age
cookie 还可以限制时间范围,通过 Expires、Max-Age 中的一种。
3.Secure / HttpOnly
cookie 可以限制使用方式。
Http头对cookie的读写:
响应会携带一个Set-Cookie头,一个Set-Cookie只能设置一条cookie,格式为cookie键值+配置键值,如果想要一次设置多个cookie,我们可以多写几个Set-Cookie在头里面。
而当浏览器请求服务器的时候,就不再需要发送配置内容了,只需要发送键值对就可以
前端对cookie的读写 *** 作:
如果服务端设置的cookie并没有设置httpOnly,那么我们就可以调用document.cookie来对cookie进行读写 *** 作,但一次调用document.cookie就只能 *** 作一个cookie
在上面我们介绍了cookie,可以了解到cookie其实是浏览器存储的一种实现,可以看作应用鉴权的基石。但是它只是一个存储信息的工具,我们还需要判断其中的信息是不是安全的 *** 作者,这时候我们就需要session了。
典型的session登录流程:
session的存储与过期销毁:
由于session是用来验证的,所以服务端仅仅只是给浏览器的cookie中添加一个sessionid,所以也需要自己保存一下,存储的方式:
而session也可以手动设置过期时间,一到过期时间就直接清空存储的内存就好了
session的分布式问题:
由于服务端是集群,而用户请求过来会走一次负载均衡,不一定会打到哪台机器上。一旦用户后续接口请求到的机器和他登录请求的机器不一样,或者登录请求的机器出问题了,那session就会失效。
常见的解决方式:
目前主流的token存储还是在cookie中进行,但是为了防止伪造token造成的安全问题,我们还需要一些加密算法来生成签名,来保证数据安全性
业务接口用来鉴权的 token,我们称之为 access token。越是权限敏感的业务,我们越希望 access token 有效期足够短,以避免被盗用。但过短的有效期会造成 access token 经常过期,过期后怎么办呢?
一种办法是,让用户重新登录获取新 token,显然不够友好,要知道有的 access token 过期时间可能只有几分钟。
另外一种办法是,再来一个 token,一个专门生成 access token 的 token,我们称为 refresh token。
如果refresh token过期了,就只能重新登陆了。
客户端存cookie与存放于其他地方
1.出了浏览器环境之外就没有cookie了;
2.cookie是浏览器在域下自动携带的。很容易引发CSFR攻击
存放在别的地方可以解决部分问题
服务端存储数据于不存
1.存数据的话可以缩短认证字符串的长度,减小请求体积
2.不存数据就不会出现分布式处理的问题,降低硬件成本,避免查库带来的验证延迟
前面我们已经知道了,在同域下的客户端/服务端认证系统中,通过客户端携带凭证,维持一段时间内的登录状态。
但当我们业务线越来越多,就会有更多业务系统分散到不同域名下,就需要「一次登录,全线通用」的能力,叫做「单点登录」。
在 主域名相同 的情况下,就可以直接把cookie设置为主域名就可以实现了。
如果 主域名不同 ,我们就需要独立的认证服务,称为SSO。
如果是在浏览器之下实现,我们需要考虑其他的东西
对浏览器来说,SSO 域下返回的数据要怎么存,才能在访问 A 的时候带上?浏览器对跨域有严格限制,cookie、localStorage 等方式都是有域限制的。
这就需要也只能由 A 提供 A 域下存储凭证的能力。一般我们是这么做的:
图中我们通过颜色把浏览器当前所处的域名标记出来。注意图中灰底文字说明部分的变化。
1.HTTP 是无状态的,为了维持前后请求,需要前端存储标记
2.cookie 是一种完善的标记方式,通过 HTTP 头或 js *** 作,有对应的安全策略,是大多数状态管理方案的基石
3.session 是一种状态管理方案,前端通过 cookie 存储 id,后端存储数据,但后端要处理分布式问题
4.token 是另一种状态管理方案,相比于 session 不需要后端存储,数据全部存在前端,解放后端,释放灵活性
5.token 的编码技术,通常基于 base64,或增加加密算法防篡改,jwt 是一种成熟的编码方案
6.在复杂系统中,token 可通过 service token、refresh token 的分权,同时满足安全性和用户体验
7.session 和 token 的对比就是「用不用cookie」和「后端存不存」的对比
8.单点登录要求不同域下的系统「一次登录,全线通用」,通常由独立的 SSO 系统记录登录状态、下发 ticket,各业务系统配合存储和认证 ticket
阅读知乎文章: 鉴权必须了解的5个兄弟:cookie、session、token、jwt、单点登录 - 知乎 (zhihu.com)
一个浏览器最多可以保存300个cookie。
Microsoft 指出 Internet Explorer 8 增加 cookie 限制为每个域名 50 个,但 IE7 似乎也允许每个域名 50 个 cookie(《Update to Internet Explorer's Cookie Jar》)。
不同浏览器间 cookie 总大小也不同:
Firefox 和 Safari 允许 cookie 多达 4097 个字节, 包括名(name)、值(value)和等号。
Opera 允许 cookie 多达 4096 个字节, 包括:名(name)、值(value)和等号。
Internet Explorer 允许 cookie 多达 4095 个字节, 包括:名(name)、值(value)和等号。
注:多字节字符计算为两个字节。在所有浏览器中,任何 cookie 大小超过限制都被忽略,且永远不会被设置。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)