Appearance
- 认证 (Authentication): 你是谁。
- 授权 (Authorization): 你有权限干什么
引入基础概念
- RBAC 模型
- RBAC 即基于角色的权限访问控制(Role-Based Access Control)。这是一种通过角色关联权限,角色同时又关联用户的授权的方式
认证授权

1、Cookie 的作用
Cookie 是保存在浏览器的一个信息,Session 是保存在服务器的一个信息
使用 cookie 的登陆流程

2、分布式 session
分时式 session 会遇到的问题:
举个例子:假如我们部署了两份相同的服务 A,B,用户第一次登陆的时候 ,Nginx 通过负载均衡机制将用户请求转发到 A 服务器,此时用户的 Session 信息保存在 A 服务器。结果,用户第二次访问的时候 Nginx 将请求路由到 B 服务器,由于 B 服务器没有保存 用户的 Session 信息,导致用户需要重新进行登陆。
这里的问题就是需要将 session 能够同步到所有关联的服务器,并通过浏览器的 cookie 能够进行授权访问
常见的解决方案:
- 某个用户的所有请求都通过特性的哈希策略分配给同一个服务器处理。这样的话,每个服务器都保存了一部分用户的 Session 信息。服务器宕机,其保存的所有 Session 信息就完全丢失了。
- 每一个服务器保存的 Session 信息都是互相同步的,也就是说每一个服务器都保存了全量的 Session 信息。每当一个服务器的 Session 信息发生变化,我们就将其同步到其他服务器。这种方案成本太大,并且,节点越多时,同步成本也越高。
- 单独使用一个所有服务器都能访问到的数据节点(比如缓存)来存放 Session 信息。为了保证高可用,数据节点尽量要避免是单点。
- Spring Session 是一个用于在多个服务器之间管理会话的项目。它可以与多种后端存储(如 Redis、MongoDB 等)集成,从而实现分布式会话管理。通过 Spring Session,可以将会话数据存储在共享的外部存储中,以实现跨服务器的会话同步和共享。
使用 session 进行登陆会遇到的问题:
当别人拿取到你浏览器中的 cookie 信息,可用进行非法请求访问(获取到你 cookie 中的 session ID信息),并不能禁止 CSRF 攻击。(跨站请求伪造)
而 token 一般会存放到 Local Storage 中

看了一下为啥跳转链接 cookie 会有风险,一个需要显式携带,一个是浏览器自动附带。

3、JWT
JWT 本身也是 Token,一种规范化之后的 JSON 结构的 Token。
JWT 自身包含了身份验证所需要的所有信息,因此,我们的服务器不需要存储 Session 信息。这显然增加了系统的可用性和伸缩性,大大减轻了服务端的压力。
组成结构:头部、有效载荷、签名

JWT 本质上就是一组字串,通过(.)切分成三个为 Base64 编码的部分:
- Header : 描述 JWT 的元数据,定义了生成签名的算法以及
Token的类型。 - Payload : 用来存放实际需要传递的数据
- Signature(签名):服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。
JWT 通常是这样的:xxxxx.yyyyy.zzzzz。
一般我们会将 token 存放到 redis 中,通过判定它过期时间以及 是否当前用户在 redis 中的 token 和 前端的 token 进行一一匹配,进行认证。
4、单点登陆 SSO
SSO 英文全称 Single Sign On,单点登录。SSO 是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
用户在浏览需要登录的页面时,客户端将 AuthToken 提交给 SSO 服务校验登录状态/获取用户登录信息
对于登录信息的存储,建议采用 Redis,使用 Redis 集群来存储登录信息,既可以保证高可用,又可以线性扩充。同时也可以让 SSO 服务满足负载均衡/可伸缩的需求。
登陆操作相关的流程图可以看一下这个: https://javaguide.cn/system-design/security/sso-intro.html#跨域登录、登出

5、OAuth2
OAuth 2.0是一个开放标准的授权协议,允许第三方应用获得有限的访问权限,以代表资源所有者(如用户)访问其在资源服务器上的资源,而无需将用户名和密码直接暴露给第三方应用。
【第三方授权】
参考