认证授权
认证 (Authentication) 和授权 (Authorization)
简单来说。认证 (Authentication):你是谁。授权 (Authorization):你有权限干什么。
Authentication(认证):验证你的身份的凭据(例如用户名和密码),通过这个凭据,系统知道存在你这个用户。所以,Authentication 被称为身份/用户验证。
Authorization(授权):发生在 Authentication 之后,管理我们访问系统的权限。如,有些资源只能具有特定权限的人才能访问(如:admin)。
在系统中被结合在一起使用,目的就是为了保护系统的安全性。
Cookie
Cookie的作用
维基百科定义 Cookie:Cookies是某些网站为了识别用户身份而储存在用户本地终端上的数据(通常经过加密)。
简单来说: Cookie 存放在客户端,一般用来保存用户信息。
Cookie 的应用案例:
1、在 Cookie 中保存已经登录过的用户信息,下次访问网站的时候页面可以自动填充一些基本信息。除此之外,Cookie 还能保存用户首选项,主题和其他设置信息。
2、用Cookie 保存 session 或者 token ,向后端发送请求的时候带上 Cookie,这样后端就能取到session或者token了。能记录用户当前的状态,因为 HTTP 协议是无状态的。
3、Cookie 用来记录和分析用户行为。网上购物的时候,因为HTTP协议是没有状态的,如果服务器想要获取你在某个页面的看了哪些商品,一种常用的实现方式就是将这些信息存放在Cookie。
如何在服务端使用 Cookie
1、设置cookie返回给客户端
1 |
|
2、用Spring框架提供的@CookieValue注解,获取特定的 cookie
1 |
|
3、读取所有的 Cookie
1 |
|
Session
Cookie 和 Session 的区别
Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。
服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。
Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。相对来说 Session 安全性更高。
如果使用 Cookie 的一些敏感信息,不应该写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。
如何使用 Session 进行身份验证
很多时候我们都是通过 SessionID 来实现特定的用户,SessionID 一般会选择存放在 Redis 中。
例如:用户成功登陆系统,然后返回给客户端具有 SessionID 的 Cookie,当用户向后端发起请求的时候会把 SessionID 带上,这样后端就知道你的身份状态了。
使用 Session 的时候需要注意下面几个点:
1、依赖 Session 的关键业务一定要确保客户端开启了 Cookie。
2、注意 Session 的过期时间。
如果没有 Cookie,Session 还能用吗
一般是通过 Cookie 来保存 SessionID,假如你使用了 Cookie 保存 SessionID,如果客户端禁用了Cookie,那么Seesion就无法正常工作。
但是,并不是没有 Cookie 之后就不能用 Session 了。如:你可以将 SessionID 放在请求的 url 的参数里面。
这种方案的话可行,但是安全性和用户体验感会降低。当然,为了安全可以对 SessionID 进行一次加密之后再传入后端。
Cookie 无法防止CSRF攻击,而token可以的原因
CSRF(Cross Site Request Forgery)译为 跨站请求伪造。
简单来说,是用你的身份去发送一些对你不友好的请求。
进行 Session 认证的时候,我们一般使用 Cookie 来存储 SessionId。登陆以后,后端生成一个 SessionId 放在 Cookie 中返回给客户端,服务端通过 Redis 或者数据库记录保存着这个Sessionid。
客户端登录以后每次请求都会带上这个 SessionId,服务端通过这个 SessionId 来标识用户。如果别人通过 cookie 拿到了 SessionId 后就可以顶替你的身份访问系统。
Session 认证中 Cookie 中的 SessionId 是由浏览器发送到服务端的,借助这个特性,攻击者就可以通过让用户误点攻击链接,达到攻击效果。
但是,使用 token 不会存在这个问题,在我们登录成功获得 token 之后,一般会选择存放在 local storage 中。
然后前端通过某些方式会给每个发到后端的请求加上这个 token,这样就不会出现 CSRF 漏洞的问题。
因为,即使你点击了非法链接发送了请求到服务端,这个非法请求是不会携带 token 的,所以这个请求将是非法的。
不论是 Cookie 还是 token 都无法避免跨站脚本攻击(Cross Site Scripting)XSS。
XSS 攻击者会用各种方式将恶意代码注入到其他用户的页面中,可以通过脚本盗用信息(如:cookie)。
Token
Web 领域基于 Token 的身份验证随处可见。在大多数使用 Web API 的互联网公司中,tokens 是多用户下处理认证的最佳方式,大部分见到过的Web应用都使用 tokens。
Session 信息需要保存一份在服务器端。这种方式会带来一些麻烦,如:需要我们保证 Session 信息服务器的可用性、不适合移动端(依赖Cookie)等。
不需要自己存放 Session 信息就能实现身份验证的方式是,使用 Token 即可。
JWT
JWT (JSON Web Token) 就是这种方式的实现,这种方式服务器端不需要保存 Session 数据,客户端保存服务端返回给客户的 Token 就可以。
JWT 本质上就一段签名的 JSON 格式的数据。由于它是带有签名的,因此接收者便可以验证它的真实性。
JWT 由 3 部分构成:
1、Header: 描述 JWT 的元数据。定义了生成签名的算法以及 Token 的类型。
2、Payload(负载): 用来存放实际需要传递的数据。
3、Signature(签名): 服务器通过Payload、Header和一个密钥(secret)使用 Header 里面指定的签名算法(默认 HMAC SHA256)生成。
基于 Token 进行身份验证
1、用户向服务器发送用户名和密码,用于登陆系统。
2、身份验证服务响应并返回了签名的 JWT,上面包含了用户是谁的内容。
3、用户之后每次向后端发请求都在Header中带上 JWT。
4、服务端检查 JWT 并从中获取用户相关信息。
OAuth
OAuth 是一个行业的标准授权协议,主要用来授权第三方应用获取有限的权限。
OAuth2.0 是对 OAuth1.0 的完全重新设计,OAuth2.0 更快,更容易实现。
实际上它就是一种授权机制,它的最终目的是为第三方应用颁发一个有时效性的令牌 token,使得第三方应用能够通过该令牌获取相关的资源。
OAuth2.0 比较常用的场景就是第三方登录,当你的网站接入了第三方登录的时候一般就是使用的 OAuth2.0 协议。
另外,OAuth2.0 也常见于支付场景(微信支付、支付宝支付)和开发平台(微信开放平台、阿里开放平台)。
SSO
SSO(Single Sign On),即单点登录。
用户登陆多个子系统的其中一个,就有权访问与其相关的其他系统。如:登陆了京东金融之后,同时也成功登陆京东的京东超市等子系统。
SSO 与 OAuth2.0 的区别
OAuth 是一个行业的标准授权协议,主要用来授权第三方应用获取有限的权限。
SSO 解决的是一个公司的多个相关的自系统的之间的登陆问题。