6 Auth Flashcards
Cookie 和 Session 有什么区别?
Session 的主要作用就是通过服务端记录用户的状态。 典型的场景是购物⻋,当你要添加商品到购物 ⻋的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定 的 Session 之后就可以标识这个用户并且跟踪这个用户了。
Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。相对来说 Session 安全性更 高。如果使用 Cookie 的一些敏感信息不要写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的 时候再去服务器端解密。
如何使用Session进行身份验证?
很多时候我们都是通过 SessionID 来实现特定的用户,SessionID 一般会选择存放在 Redis 中。举个 例子:用户成功登陆系统,然后返回给客户端具有 SessionID 的 Cookie,当用户向后端发起请求的时 候会把 SessionID 带上,这样后端就知道你的身份状态了。关于这种认证方式更详细的过程如下:
- 用户向服务器发送用户名和密码用于登陆系统。
- 服务器验证通过后,服务器为用户创建一个 Session,并将 Session信息存储 起来。
- 服务器向用户返回一个 SessionID,写入用户的 Cookie。
- 当用户保持登录状态时,Cookie 将与每个后续请求一起被发送出去。
- 服务器可以将存储在 Cookie 上的 Session ID 与存储在内存中或者数据库中的 Session 信息
进行比,以验证用户的身份,返回给用户客户端响应信息的时候会附带用户当前的状态。
(经典面试题) 如果没有Cookie的话Session还能用吗?
一般是通过 Cookie 来保存 SessionID ,假如你使用了 Cookie 保存 SessionID的方案的话, 如果客 户端禁用了Cookie,那么Seesion就无法正常工作。
但是,并不是没有 Cookie 之后就不能用 Session 了,比如你可以将SessionID放在请求的 url 里面https://javaguide.cn/?session_id=xxx 。
这种方案的话可行,但是安全性和用户体验感降 低。当然,为了你也可以对 SessionID 进行一次加密之后再传入后端。
6.1.5 为什么Cookie 无法防止CSRF攻击,而token可以?
CSRF(Cross Site Request Forgery)一般被翻译为 跨站请求伪造 。那么什么是 跨站请求伪造 呢?
说简单用你的身份去发送一些对你不友好的请求。举个简单的例子:
小壮登录了某网上银行,他来到了网上银行的帖子区,看到一个帖子下面有一个链接写着“科学理财, 年盈利率过万”,小壮好奇的点开了这个链接,结果发现自己的账户少了10000元。这是这么回事呢?原 来黑客在链接中藏了一个请求,这个请求直接利用小壮的身份给银行发送了一个转账请求,也就是通过 你的 Cookie 向银行发出请求。
上面也提到过,进行Session 认证的时候,我们一般使用 Cookie 来存储 SessionId,当我们登陆后后 端生成一个SessionId放在Cookie中返回给客户端,服务端通过Redis或者其他存储工具记录保存着这个 Sessionid,客户端登录以后每次请求都会带上这个SessionId,服务端通过这个SessionId来标示你这 个人。如果别人通过 cookie拿到了 SessionId 后就可以代替你的身份访问系统了。
Session 认证中 Cookie 中的 SessionId是由浏览器发送到服务端的,借助这个特性,攻击者就可以通 过让用户误点攻击链接,达到攻击效果。
但是,我们使用 token 的话就不会存在这个问题,在我们登录成功获得 token 之后,一般会选择存放 在 local storage 中。然后我们在前端通过某些方式会给每个发到后端的请求加上这个 token,这样就 不会出现 CSRF 漏洞的问题。因为,即使有个你点击了非法链接发送了请求到服务端,这个非法请求是 不会携带 token 的,所以这个请求将是非法的。
6.1.6 什么是 Token?什么是 JWT?如何基于Token进行身份验证?
我们在上一个问题中探讨了使用 Session 来鉴别用户的身份,并且给出了几个 Spring Session 的案 例分享。 我们知道 Session 信息需要保存一份在服务器端。这种方式会带来一些麻烦,比如需要我们 保证保存 Session 信息服务器的可用性、不适合移动端(依赖Cookie)等等。
有没有一种不需要自己存放 Session 信息就能实现身份验证的方式呢?使用 Token 即可!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 进行身份验证的的应用程序中,服务器通过Payload、Header和一个密钥(secret) 创建令牌( Token )并将 Token 发送给客户端,客户端将 Token 保存在 Cookie 或者localStorage 里面,以后客户端发出的所有请求都会携带这个令牌。你可以把它放在 Cookie 里面自 动发送,但是这样不能跨域,所以更好的做法是放在 HTTP Header 的 Authorization字段 中:Authorization: Bearer Token。
- 用户向服务器发送用户名和密码用于登陆系统。
- 身份验证服务响应并返回了签名的 JWT,上面包含了用户是谁的内容。
- 用户以后每次向后端发请求都在Header中带上 JWT。
- 服务端检查 JWT 并从中获取用户相关信息。
什么是OAuth2?
OAuth 是一个行业的标准授权协议,主要用来授权第三方应用获取有限的权限。而 OAuth 2.0是对 OAuth 1.0 的完全重新设计,OAuth 2.0更快,更容易实现,OAuth 1.0 已经被废弃。详情请 ⻅:rfc6749。
实际上它就是一种授权机制,它的最终目的是为第三方应用颁发一个有时效性的令牌 token,使得第三 方应用能够通过该令牌获取相关的资源。
OAuth 2.0 比较常用的场景就是第三方登录,当你的网站接入了第三方登录的时候一般就是使用的 OAuth 2.0 协议。
另外,现在OAuth 2.0也常⻅于支付场景(微信支付、支付宝支付)和开发平台(微信开放平台、阿里 开放平台等等)。
6.1.8 什么是 SSO? SSO与OAuth2.0的区别是什么?
SSO(Single Sign On)即单点登录说的是用户登陆多个子系统的其中一个就有权访问与其相关的其他系统。举个例子我们在登陆了京东金融之后,我们同时也成功登陆京东的京东超市、京东家电等子系统。
OAuth 是一个行业的标准授权协议,主要用来授权第三方应用获取有限的权限。是实现SSO的一种方式
OAuth2的授权模式有哪几种?各自的flow是什么样子的?
- Authorization Code
- Implicit (access token to Client Browser)
- Password
- Client Credentials
ref: http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html