认证
cookie和session
cookie和session说白了就是个map。
cookie存放在客户端(如浏览器),记录的内容通常是加密的。
- 记录用户当前的状态(HTTP 协议是无状态);
- 记录和分析用户行为(如看了哪些商品)等。
session保存在服务器端
集群下session-cookie方案
服务器中的session保存已经登录的用户信息,然后将可以识别当前登录用户的id发送给客户端的cookie保存。
通常情况下为了解决集群下的可用性和一致性会有3个方案:
hash策略总能让同一个用户的请求落到同一台服务器上;
主从同步,让所有的集群服务器的数据都相同,才返回响应成功;
引入第三方,如redis,来保存用户的信息,替代传统的服务器单机session。
即使cookie被客户端禁用了,也可以用其它方代替,毕竟它本身存的就是一个可以验证用户身份的识别码,随便用个请求参数一样可以代替。
token防止CSRF
CSRF(Cross Site Request Forgery): 跨站请求伪造 。用你的身份去发送一些对你不友好的请求。
使用cookie验证身份时,如果误点击了别人精心构造的恶意链接,而这条链接符合正常链接的请求形式,只不过是你根本不打算做的操作,比如,向某人转账,此时当你点击了这条不知道真正内容是啥的链接,并携带了该网站的cookie(包含身份验证信息)发送到服务器,服务器识别,是本人发起的请求,然后向某人进行了转账。这就是CSRF攻击。【攻击者不需要知道cookie的内容】
而使用token就可以避免这种恶意链接带来的恶果,token本质上就是当用户登录后一串由服务器生成的随机数字,并将该token绑定好该用户,并规定只有请求中包含token参数时,才是一条合法的链接。然后将该token串返回给客户端,由localStorage保存,之后每次发起请求时都应携带该参数(放在请求参数中或在请求头都可以)。
token的两个作用:
必须携带token参数,链接才是合法链接。
服务器验证token参数是否有已经登录的用户进行了合法绑定。
攻击者如果想攻击成功,必须得知道token的具体值,才能伪造某用户的请求
XSS
token阻止了CSRF攻击,如果想攻击成功,就必须得知道token的具体值,而XSS就可以获得这些信息。
XSS(Cross Site Scripting):跨站脚本攻击,为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击!
分为两种:
反射型(临时的)
存储型(持久化到数据库)
反射型:请求中有个参数,后台接收到后不做任何检查,也不存放到数据库,总之是在业务中用完了,基于某种需求,需要返回给前台,并将其动态输出在了dom页面(当然,页面刷新一下就没了),如果是参数内容是js,将会被浏览器解释执行。
此时,如果攻击者A发现这个参数可以存放js脚本,并且还会被浏览器解释执行,那么他可以尝试构造一段通过js获取本地cookie或者localStorage里的内容之类的东西,然后将这些内容再发送到他准备好的一个服务器上。A将这段js脚本压缩一下然后放在参数内容里,并将这条请求随便发给某个受害者B,
B是该网站的用户,他的浏览器中当然存放着cookie等信息,然后B收到了A给的链接请求,他不知道是啥,反正B点了,然后B构造的js就开始在A的浏览器中执行了,因此A得到了B的cookie和localStorage的信息。
存储型:请求中有个参数,后台仍然不做检查,但是这个参数的内容根据业务需求,需要被存到数据库中,然后再将其返回到前台显示。(如评论一样的东西)
攻击者A构造同样的脚本,只不过这次他不需要构造链接,让其他用户去点击了,他直接利用评论所在的页面会被所有访问过该页面的人看到这一特性,将js拼接到参数中发给服务器。像B这样的用户,只要访问了评论页面,那么脚本执行,A就会收到B的所有存储在本地的信息(只要A想)。
因此即使是token存放进localStorage,只要被XSS攻击,一样以获取到信息,从而替代原用户进行操作。
Json Web Token
之前要验证用户,必须得是前端也存,后端也存,而JWT则只需要前端存,在发起请求到后台后,只需要验证它的真实性即可。
JWT:带签名的 JSON 格式的token。由于它是带有签名的,因此接收者便可以验证它的真实性。
JWT 由 3 部分构成:
Header : 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。
Payload : 用来存放实际需要传递的数据(用户id啥的可以表明是哪个用户的信息)
Signature(签名):服务器使用 Header 里面指定的签名算法(默认是 HMAC SHA256),将Header、Payload和一个secret (密钥)做入参,计算生成。
使用JWT
由于cookie不能跨域,因此服务器生成的JWT最好别放cookie里,更好的做法是放在 HTTP Header 的 Authorization 字段中:Authorization: Bearer {Token}。
- 用户向服务器发送用户名和密码用于登陆系统。
- 身份验证服务响应并返回了签名的 JWT,上面包含了用户是谁的内容。
- 用户以后每次向后端发请求都在 Header 中带上 JWT。
- 服务端检查 JWT 并从中获取用户相关信息。
同样的,JWT只要保存在客户端,就可能被XSS获得。
SSO单点登录
https://www.cnblogs.com/ywlaker/p/6113927.html#!comments
基于JWT。
sso-client
拦截子系统未登录用户请求,跳转至sso认证中心
接收并存储sso认证中心发送的令牌
与sso-server通信,校验令牌的有效性
建立局部会话
拦截用户注销请求,向sso认证中心发送注销请求
接收sso认证中心发出的注销请求,销毁局部会话
sso-server
验证用户的登录信息
创建全局会话
创建授权令牌
与sso-client通信发送令牌
校验sso-client令牌有效性
系统注册
接收sso-client注销请求,注销所有会话
假设认证中心和系统2的url分别是:sso.com、system2.com,
访问
system2.com 时因未登录而跳转到
sso.com,跳转地址:http://sso.com?service=http://system2.com`(不需要额外信息)`,