1
0

系统权限:鉴权解决方案

This commit is contained in:
周中平 2022-08-31 15:59:07 +08:00
parent 562dbc04bd
commit c00249e1d3
No known key found for this signature in database
GPG Key ID: B1DF9DD42D8E00DC
16 changed files with 944 additions and 43 deletions

View File

@ -316,7 +316,7 @@ const config = {
theme: lightCodeTheme, theme: lightCodeTheme,
darkTheme: darkCodeTheme, darkTheme: darkCodeTheme,
defaultLanguage: "markdown", defaultLanguage: "markdown",
additionalLanguages: ["java", "git","nginx"], additionalLanguages: ["java", "git","nginx","http"],
}, },
}), }),
}; };

View File

@ -5,8 +5,7 @@ keywords:
- 关键字 - 关键字
tags: tags:
- 标签 - 标签
sidebar_position: 1
author: 7Wate author: 7Wate
date: <% tp.date.now("YYYY-MM-DD") %> date: <% tp.date.now("YYYY-MM-DD") %>
--- ---
一篇文档 - 快速模板

View File

@ -0,0 +1,8 @@
{
"label": "权限设计方案",
"position": 2,
"link": {
"type": "generated-index",
"title": "权限设计方案"
}
}

View File

@ -14,39 +14,39 @@ data: 2022年08月08日
- **ABAC模型**:基于属性的访问控制 - **ABAC模型**:基于属性的访问控制
- **RBAC模型**:基于角色的权限访问控制 - **RBAC模型**:基于角色的权限访问控制
## ACL模型访问控制列表 ## ACL 模型:访问控制列表
**Access Control List**ACL是最早的、最基本的一种访问控制机制是基于客体进行控制的模型在其他模型中也有ACL的身影。为了解决相同权限的用户挨个配置的问题后来也采用了用户组的方式。 **Access Control List**ACL 是最早的、最基本的一种访问控制机制,是基于客体进行控制的模型,在其他模型中也有 ACL 的身影。为了解决相同权限的用户挨个配置的问题,后来也采用了用户组的方式。
**原理**:每一个客体都有一个列表,列表中记录的是哪些主体可以对这个客体做哪些行为,非常简单。 **原理**:每一个客体都有一个列表,列表中记录的是哪些主体可以对这个客体做哪些行为,非常简单。
**例如**当用户A要对一篇文章进行编辑时ACL会先检查一下文章编辑功能的控制列表中有没有用户A有就可以编辑无则不能编辑。再例如不同等级的会员在产品中可使用的功能范围不同。 **例如**当用户A要对一篇文章进行编辑时ACL 会先检查一下文章编辑功能的控制列表中有没有用户 A有就可以编辑无则不能编辑。再例如不同等级的会员在产品中可使用的功能范围不同。
**缺点**:当主体的数量较多时,配置和维护工作就会成本大、易出错。 **缺点**:当主体的数量较多时,配置和维护工作就会成本大、易出错。
## DAC模型自主访问控制 ## DAC 模型:自主访问控制
Discretionary Access ControlDAC是ACL的一种拓展。 Discretionary Access ControlDAC ACL 的一种拓展。
**原理**在ACL模型的基础上允许主体可以将自己拥有的权限自主地授予其他主体所以权限可以任意传递。 **原理**:在 ACL 模型的基础上,允许主体可以将自己拥有的权限自主地授予其他主体,所以权限可以任意传递。
**例如**常见于文件系统LINUXUNIX、WindowsNT版本的操作系统都提供DAC的支持。 **例如**常见于文件系统LINUXUNIX、WindowsNT 版本的操作系统都提供 DAC 的支持。
**缺点**:对权限控制比较分散,例如无法简单地将一组文件设置统一的权限开放给指定的一群用户。主体的权限太大,无意间就可能泄露信息。 **缺点**:对权限控制比较分散,例如无法简单地将一组文件设置统一的权限开放给指定的一群用户。主体的权限太大,无意间就可能泄露信息。
## MAC模型强制访问控制 ## MAC 模型:强制访问控制
**Mandatory Access Control**MAC模型中主要的是双向验证机制。常见于机密机构或者其他等级观念强烈的行业如军用和市政安全领域的软件。 **Mandatory Access Control**MAC 模型中主要的是双向验证机制。常见于机密机构或者其他等级观念强烈的行业,如军用和市政安全领域的软件。
**原理**:主体有一个权限标识,客体也有一个权限标识,而主体能否对该客体进行操作取决于双方的权限标识的关系。 **原理**:主体有一个权限标识,客体也有一个权限标识,而主体能否对该客体进行操作取决于双方的权限标识的关系。
**例如**:将军分为上将>中将>少将,军事文件保密等级分为绝密>机密>秘密,规定不同军衔仅能访问不同保密等级的文件,如少将只能访问秘密文件;当某一账号访问某一文件时,系统会验证账号的军衔,也验证文件的保密等级,当军衔和保密等级相对应时才可以访问。 **例如**:将军分为上将 > 中将 > 少将,军事文件保密等级分为绝密 > 机密 > 秘密,规定不同军衔仅能访问不同保密等级的文件,如少将只能访问秘密文件;当某一账号访问某一文件时,系统会验证账号的军衔,也验证文件的保密等级,当军衔和保密等级相对应时才可以访问。
**缺点**:控制太严格,实现工作量大,缺乏灵活性。 **缺点**:控制太严格,实现工作量大,缺乏灵活性。
## ABAC模型基于属性的访问控制 ## ABAC 模型:基于属性的访问控制
**Attribute-Based Access Control**能很好地解决RBAC的缺点在新增资源时容易维护。 **Attribute-Based Access Control**,能很好地解决 RBAC 的缺点,在新增资源时容易维护。
**原理**:通过动态计算一个或一组属性是否满足某种机制来授权,是一种很灵活的权限模型,可以按需实现不同颗粒度的权限控制。 **原理**:通过动态计算一个或一组属性是否满足某种机制来授权,是一种很灵活的权限模型,可以按需实现不同颗粒度的权限控制。
@ -57,7 +57,7 @@ Discretionary Access ControlDAC是ACL的一种拓展。
3. 环境属性,即空间限制、时间限制、频度限制; 3. 环境属性,即空间限制、时间限制、频度限制;
4. 操作属性,即行为类型,如读写、只读等。 4. 操作属性,即行为类型,如读写、只读等。
**例如**早上9:0011:00期间A、B两个部门一起以考生的身份考试下午14:0017:00期间A、B两个部门相互阅卷。 **例如**:早上 9:0011:00 期间 A、B 两个部门一起以考生的身份考试,下午 14:0017:00 期间 A、B 两个部门相互阅卷。
**缺点**:规则复杂,不易看出主体与客体之间的关系,实现非常难,现在应用的很少。 **缺点**:规则复杂,不易看出主体与客体之间的关系,实现非常难,现在应用的很少。
@ -65,13 +65,13 @@ Discretionary Access ControlDAC是ACL的一种拓展。
**Role-Based Access Control**,核心在于用户只和角色关联,而角色代表对了权限,是一系列权限的集合。 **Role-Based Access Control**,核心在于用户只和角色关联,而角色代表对了权限,是一系列权限的集合。
RBAC三要素 RBAC 三要素:
1. **用户**:系统中所有的账户 1. **用户**:系统中所有的账户
2. **角色**:一系列权限的集合(如:管理员,开发者,审计管理员等) 2. **角色**:一系列权限的集合(如:管理员,开发者,审计管理员等)
3. **权限**:菜单,按钮,数据的增删改查等详细权限。 3. **权限**:菜单,按钮,数据的增删改查等详细权限。
在**RBAC**中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。 **RBAC **中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。
角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。 角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。
@ -79,51 +79,51 @@ RBAC三要素
**优点**:便于角色划分,更灵活的授权管理;最小颗粒度授权; **优点**:便于角色划分,更灵活的授权管理;最小颗粒度授权;
![基于角色的权限控制](https://static.7wate.com/img/2022/08/08/e11745fdd5e0f.png) ![RBAC](https://static.7wate.com/img/2022/08/30/2fb0d9ad61795.png)
## RBAC的深度拓展 ## RBAC的深度拓展
RBAC模型可以分为**RBAC0**、**RBAC1**、**RBAC2**、**RBAC3** 四个阶段,一般公司使用**RBAC0**的模型就可以。另外,**RBAC0**相当于底层逻辑,后三者都是在**RBAC0**模型上的拔高。 RBAC模型可以分为**RBAC0**、**RBAC1**、**RBAC2**、**RBAC3** 四个阶段,一般公司使用 **RBAC0** 的模型就可以。另外,**RBAC0** 相当于底层逻辑,后三者都是在 **RBAC0** 模型上的拔高。
我先简单介绍下这四个RBAC模型 我先简单介绍下这四个RBAC模型
### 1. RBAC0模型 ### 1. RBAC0 模型
用户和角色、角色和权限多对多关系。 用户和角色、角色和权限多对多关系。
简单来说就是一个用户拥有多个角色,一个角色可以被多个用户拥有,这是用户和角色的多对多关系;同样的,角色和权限也是如此。 简单来说就是一个用户拥有多个角色,一个角色可以被多个用户拥有,这是用户和角色的多对多关系;同样的,角色和权限也是如此。
**RBAC0**模型如下图:没有画太多线,但是已经能够看出多对多关系。 **RBAC0** 模型如下图:没有画太多线,但是已经能够看出多对多关系。
![RBAC0](https://static.7wate.com/img/2022/08/08/cf466dbdf2bcd.png) ![RBAC0](https://static.7wate.com/img/2022/08/30/704178e086081.png)
### 2. RBAC1模型 ### 2. RBAC1 模型
相对于**RBAC0**模型,增加了**角色分级**的逻辑,类似于树形结构,下一节点继承上一节点的所有权限,如**role1**根节点下有**role1.1**和**role1.2**两个子节点 相对于 **RBAC0 **模型,增加了**角色分级**的逻辑,类似于树形结构,下一节点继承上一节点的所有权限,如 **role1** 根节点下有 **role1.1** **role1.2** 两个子节点
![RBAC1](https://static.7wate.com/img/2022/08/08/ca7afbb3e8cac.png) ![RABC1](https://static.7wate.com/img/2022/08/30/ab50d1c150699.png)
角色分级的逻辑可以有效的规范角色创建主要得益于权限继承逻辑我之前做过BD工具类CRMBD之间就有分级经理、主管、专员如果采用RBAC0模型做权限系统我可能需要为经理、主管、专员分别创建一个角色角色之间权限无继承性极有可能出现一个问题由于权限配置错误主管拥有经理都没有权限。 角色分级的逻辑可以有效的规范角色创建(主要得益于权限继承逻辑),我之前做过 BD 工具(类 CRM BD 之间就有分级(经理、主管、专员),如果采用 RBAC0 模型做权限系统,我可能需要为经理、主管、专员分别创建一个角色(角色之间权限无继承性),极有可能出现一个问题,由于权限配置错误,主管拥有经理都没有权限。
而RBAC1模型就很好解决了这个问题创建完经理角色并配置好权限后主管角色的权限继承经理角色的权限并且支持针对性删减主管权限。 RBAC1 模型就很好解决了这个问题,创建完经理角色并配置好权限后,主管角色的权限继承经理角色的权限,并且支持针对性删减主管权限。
### 3. RBAC2模型 ### 3. RBAC2 模型
基于**RBAC0**模型,对角色增加了更多约束条件。 基于 **RBAC0** 模型,对角色增加了更多约束条件。
![RBAC2](https://static.7wate.com/img/2022/08/08/83e2b3f4e2f85.png) ![RBAC2](https://static.7wate.com/img/2022/08/30/adc688e2b7f77.png)
如**角色互斥**,比较经典的案例是财务系统中出纳不得兼管稽核,那么在赋予财务系统操作人员角色时,同一个操作员不能同时拥有出纳和稽核两个角色。 如**角色互斥**,比较经典的案例是财务系统中出纳不得兼管稽核,那么在赋予财务系统操作人员角色时,同一个操作员不能同时拥有出纳和稽核两个角色。
如**角色数量限制**例如一个角色专门为公司CEO创建的最后发现公司有10个人拥有CEO角色一个公司有10个CEO这就是对角色数量的限制它指的是有多少用户能拥有这个角色。 如**角色数量限制**,例如:一个角色专门为公司 CEO 创建的,最后发现公司有 10 个人拥有 CEO 角色一个公司有10 CEO ?这就是对角色数量的限制,它指的是有多少用户能拥有这个角色。
**RBAC2** 模型主要是为了增加角色赋予的限制条件,这也符合权限系统的目标:权责明确,系统使用安全、保密。 **RBAC2** 模型主要是为了增加角色赋予的限制条件,这也符合权限系统的目标:权责明确,系统使用安全、保密。
### 4. RBAC3模型 ### 4. RBAC3模型
同样是基于**RBAC0**模型,但是综合了**RBAC1**和**RBAC2**的所有特点 同样是基于 **RBAC0** 模型,但是综合了 **RBAC1** **RBAC2** 的所有特点
这里就不在多描述,读者返回去看**RBAC1**和**RBAC2**模型的描述即可。 这里就不在多描述,读者返回去看 **RBAC1** **RBAC2** 模型的描述即可。
## RBAC 权限管理的在实际系统中的应用 ## RBAC 权限管理的在实际系统中的应用
@ -135,15 +135,15 @@ RBAC 权限模型由三大部分构成,即**用户管理**、**角色管理**
权限管理是前两种管理的再加固,做太细容易太碎片,做太粗又不够安全,这里我们需要根据经验和实际情况来设计。 权限管理是前两种管理的再加固,做太细容易太碎片,做太粗又不够安全,这里我们需要根据经验和实际情况来设计。
### 1.用户管理 ### 1. 用户管理
用户管理中的用户,是企业里每一位员工,他们本身就有自己的组织架构,我们可以直接使用企业部门架构或者业务线架构来作为线索,构建用户管理系统。 用户管理中的用户,是企业里每一位员工,他们本身就有自己的组织架构,我们可以直接使用企业部门架构或者业务线架构来作为线索,构建用户管理系统。
![用户管理](https://static.7wate.com/img/2022/08/08/71d1e4799cbf1.png) ![用户管理系统](https://static.7wate.com/img/2022/08/30/887a6f017f7e3.png)
**需要特殊注意**:实际业务中的组织架构可能与企业部门架构、业务线架构不同,需要考虑数据共享机制,一般的做法为授权某个人、某个角色组共享某个组织层级的某个对象组数据。 **需要特殊注意**:实际业务中的组织架构可能与企业部门架构、业务线架构不同,需要考虑数据共享机制,一般的做法为授权某个人、某个角色组共享某个组织层级的某个对象组数据。
### 2.角色管理 ### 2. 角色管理
在设计系统角色时,我们应该深入理解公司架构、业务架构后,再根据需求设计角色及角色内的等级。 在设计系统角色时,我们应该深入理解公司架构、业务架构后,再根据需求设计角色及角色内的等级。
@ -177,7 +177,7 @@ RBAC 权限模型由三大部分构成,即**用户管理**、**角色管理**
权限管理一般从三个方面来做限制。**页面/菜单权限****操作权限****数据权限**。 权限管理一般从三个方面来做限制。**页面/菜单权限****操作权限****数据权限**。
![权限管理](https://static.7wate.com/img/2022/08/08/880d2c1254732.png) ![权限管理系统](https://static.7wate.com/img/2022/08/30/8ad6abcc85524.png)
#### 1. 页面/菜单权限 #### 1. 页面/菜单权限
@ -193,7 +193,7 @@ RBAC 权限模型由三大部分构成,即**用户管理**、**角色管理**
#### 4. 数据权限如何管控 #### 4. 数据权限如何管控
数据权限可以分为行权限和列权限。行权限控制:看多少条数据。列权限控制:看一条数据的多少个字段 数据权限可以分为行权限和列权限。行权限控制:看多少条数据。列权限控制:看一条数据的多少个字段
简单系统中可以通过组织架构来管控行权限,按照角色来配置列权限,但是遇到复杂情况,组织架构是承载不了复杂行权限管控,角色也更不能承载列的特殊化展示。 简单系统中可以通过组织架构来管控行权限,按照角色来配置列权限,但是遇到复杂情况,组织架构是承载不了复杂行权限管控,角色也更不能承载列的特殊化展示。
@ -205,18 +205,18 @@ RBAC 权限模型由三大部分构成,即**用户管理**、**角色管理**
## 用户管理系统权限设计中的更多实践细节 ## 用户管理系统权限设计中的更多实践细节
### 1.超级管理员 ### 1. 超级管理员
超级管理员是用来启动系统,配置系统的账号。这个账号应该在配置好系统,创建管理员之后被隐藏起来。超级管理员账号拥有系统中全部权限,可穿梭查看各部门数据,如果使用不恰当,是系统管理的安全隐患。 超级管理员是用来启动系统,配置系统的账号。这个账号应该在配置好系统,创建管理员之后被隐藏起来。超级管理员账号拥有系统中全部权限,可穿梭查看各部门数据,如果使用不恰当,是系统管理的安全隐患。
### 2.互斥角色如何处理 ### 2. 互斥角色如何处理
当用户已经有用的角色和即将添加的角色互相互斥时,应该在添加新角色时,提示管理员因角色互斥的原因,无法进行新角色添加。如需添加,要先撤销掉前一个角色,再添加新角色。 当用户已经有用的角色和即将添加的角色互相互斥时,应该在添加新角色时,提示管理员因角色互斥的原因,无法进行新角色添加。如需添加,要先撤销掉前一个角色,再添加新角色。
### 3.用户管理权限系统设计一定要简单清晰 ### 3. 用户管理权限系统设计一定要简单清晰
在设计权限系统之处,一定要理清思路,一切从简,能不增加的多余角色和权限逻辑,就一定不要增加。因为随着公司业务的扩大,权限和角色也会随之增多,如果初期设计思路不严谨,那么权限系统会随着业务的扩大而无限混乱下去,此时再来整理权限,已经太晚了。所以初期设计就一定要条理清晰,简单明了,能避免后续非常多不必要的麻烦。 在设计权限系统之处,一定要理清思路,一切从简,能不增加的多余角色和权限逻辑,就一定不要增加。因为随着公司业务的扩大,权限和角色也会随之增多,如果初期设计思路不严谨,那么权限系统会随着业务的扩大而无限混乱下去,此时再来整理权限,已经太晚了。所以初期设计就一定要条理清晰,简单明了,能避免后续非常多不必要的麻烦。
### 4.无权提示页 ### 4. 无权提示页
有时员工 A 会直接给员工 B 分享他当下正在操作的页面,但有可能员工 B 无权查看。此时我们应该在这里考虑添加「无权提示页」,避免粗暴的 404 页面让员工 B 以为是系统出错了。 有时员工 A 会直接给员工 B 分享他当下正在操作的页面,但有可能员工 B 无权查看。此时我们应该在这里考虑添加「无权提示页」,避免粗暴的 404 页面让员工 B 以为是系统出错了。

View File

@ -0,0 +1,52 @@
---
title: 系统权限简明指南
description: 系统权限简明指南
keywords:
- 系统
- 权限
tags:
- 安全
sidebar_position: 1
author: 7Wate
date: 2022-08-31
---
## 认证
**认证Identification**是指根据声明者所特有的识别信息,确认声明者的身份。**你需要用身份证证明你自己是你自己**。比如我们常见的认证技术:身份证、用户名和密码、用户手机:手机短信、手机二维码扫描、手势密码、电子邮箱、指纹、语音、眼睛虹膜、大数据识别等等
## 授权
**授权Authorization**在信息安全领域是指**资源所有者**委派**执行者**,赋予**执行者**指定范围的资源操作权限,以便对资源的相关操作。
- **现实生活领域**:银行卡(由银行派发)、门禁卡(由物业管理处派发)、钥匙(由房东派发),这些都是现实生活中授权的实现方式。
- **互联网领域** Web 服务器的 Session 机制、Web 浏览器的 Cookie 机制、颁发授权令牌Token等都是一个授权的机制。
## 鉴权
**鉴权Authentication**在信息安全领域是指**对于一个声明者所声明的身份权利,对其所声明的真实性进行鉴别确认的过程**。若从授权出发,则会更加容易理解鉴权。授权和鉴权是两个上下游相匹配的关系:**先授权,后鉴权**。
- **现实生活领域:** 门禁卡需要通过门禁卡识别器,银行卡需要通过银行卡识别器;
- **互联网领域:** 校验 Session / Cookie / Token 的合法性和有效性
**鉴权**是一个承上启下的一个环节上游它接受授权的输出校验其真实性后然后获取权限Permission这个将会为下一步的权限控制做好准备。
## 权限控制
**权限控制Access/Permission Control** 将可执行的操作定义为权限列表,然后判断操作是否允许/禁止。对于权限控制,可以分为两部分进行理解:一个是**权限**,另一个是**控制**。**权限是抽象的逻辑概念,而控制是具体的实现方式。**
- **现实生活领域:** 以门禁卡的权限实现为例,一个门禁卡,拥有开公司所有的门的权限;一个门禁卡,拥有管理员角色的权限,因而可以开公司所有的门。
- **互联网领域:** 通过 Web 后端服务,来控制接口访问,允许或拒绝访问请求。
## 认证、授权、鉴权和权限控制的关系?
![关系](https://static.7wate.com/img/2022/08/29/05d140d5e8751.png)
**认证**、**授权**、**鉴权**和**权限控制**,这四个环节是一个**前后依次发生**、**上下游**的关系;需要说明的是,这四个环节在有些时候会同时发生。 例如在下面的几个场景:
- **使用门禁卡开门:** 认证、授权、鉴权、权限控制四个环节一气呵成,在瞬间同时发生。
- **用户的网站登录:** 用户在使用用户名和密码进行登录时,认证和授权两个环节一同完成,而鉴权和权限控制则发生在后续的请求访问中,比如在选购物品或支付时。

View File

@ -0,0 +1,74 @@
---
title: HTTP 基本鉴权
description: HTTP 基本鉴权
keywords:
- HTTP
- 鉴权
tags:
- 权限
sidebar_position: 1
author: 7Wate
date: 2022-08-31
---
## HTTP 基本鉴权
在 HTTP 中,**基本认证方案Basic Access Authentication**是允许客户端(通常指的就是网页浏览器)在请求时,通过用户提供用户名和密码的方式,实现对用户身份的验证。
### 流程图
![认证流程图](https://static.7wate.com/img/2022/08/30/298b4e5cd922d.png)
### 步骤解析
1. **客户端:** 向服务器请求一个**受限的列表数据或资源**。
```http
GET /list/ HTTP/1.1
Host: www.baidu.com
Authorization: Basic aHR0cHdhdGNoOmY=
```
2. **服务器**:客户端你好,这个资源在安全区 baidu.com 里是受限资源,需要基本认证。并且向客户端返回 401 状态码 Unauthorized未授权以及附带提供了一个认证域 `www-Authenticate: Basic realm="baidu.com"` 要求进行身份验证;其中 Basic 就是验证的模式,而 `realm="baidu.com"` 说明客户端需要输入这个安全域的用户名和密码,而不是其他域的。
```http
HTTP/1.1 401 Unauthorized
www-Authenticate: Basic realm= "baidu.com"
```
3. **客户端:** 服务器,我已经携带了用户名和密码给你了,你看一下(如果客户端是浏览器,那么此时会自动弹出一个弹窗,让用户输入用户名和密码);
输入完用户名和密码后,则客户端将用户名及密码以 Base64 加密方式发送给服务器
传送的格式如下(其中 Basic 内容为:**用户名+密码的 AES 64 形式**
```http
GET /list/ HTTP/1.1
Authorization: Basic Ksid2FuZzp3YW5n==
```
4. **服务器:** 客户端你好,我已经校验了 `Authorization` 字段你的用户名和密码,是正确的,这是你要的资源。
```http
HTTP/1.1 200 OK
...
```
### 优点
简单易用,基本所有流行的浏览器都支持。
### 缺点
#### 不安全
- 由于是基于 HTTP 传输,所以它在网络上几乎是裸奔的,虽然它使用了 Base64 来编码,但这个编码很容易就可以解码出来。
- 即使认证内容无法被解码为原始的用户名和密码也是不安全的,恶意用户可以再获取了认证内容后使用其不断的享服务器发起请求,这就是所谓的重放攻击。
#### 无法主动注销
- 由于 HTTP 协议没有提供机制清除浏览器中的 Basic 认证信息,除非标签页或浏览器关闭、或用户清除历史记录。
### 使用场景
内部网络,或者对安全要求不是很高的网络。

View File

@ -0,0 +1,105 @@
---
title: JWT 鉴权
description: JWT 鉴权
keywords:
- JWT
- Java
- 鉴权
tags:
- 权限
sidebar_position: 4
author: 7Wate
date: 2022-08-31
---
## JWTJSON Web Token鉴权
通过第三节,我们知道了 Token 的使用方式以及组成,我们不难发现,服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户基本信息,然后验证 Token 是否有效;这样每次请求验证都要查询数据库,增加了查库带来的延迟等性能消耗。
**那么这时候业界常用的 JWT 就应运而生了!!!**
### JWT 的定义
JWT 是 Auth0 提出的通过对 JSON 进行加密签名来实现授权验证的方案。
就是登录成功后将相关用户信息组成 JSON 对象,然后对这个对象进行某种方式的加密,返回给客户端; 客户端在下次请求时带上这个 Token 服务端再收到请求时校验 token 合法性,其实也就是在校验请求的合法性。
### JWT 的组成
JWT 由三部分组成:**Header 头部**、**Payload 负载**和 **Signature 签名**。它是一个很长的字符串,中间用( . )分隔成三个部分。
```text
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
```
#### Header 头部
在 Header 中通常包含了两部分:
- typ代表 Token 的类型,这里使用的是 JWT 类型。
- alg使用的 Hash 算法,例如 HMAC SHA256 或 RSA。
```json
{
"alg": "HS256",
"typ": "JWT"
}
```
#### Payload 负载
它包含一些声明 Claim实体的描述通常是一个 User 信息还包括一些其他的元数据用来存放实际需要传递的数据JWT 规定了7个官方字段
- ississuer签发人
- expexpiration time过期时间
- subsubject主题
- audaudience受众
- nbfNot Before生效时间
- iatIssued At签发时间
- jtiJWT ID编号
除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。
```json
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
```
#### Signature 签名
Signature 部分是对前两部分的签名,防止数据篡改。
首先需要指定一个密钥secret。这个密钥只有服务器才知道不能泄露给用户。然后使用 Header 里面指定的签名算法(默认是 HMAC SHA256按照下面的公式产生签名。
```java
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
```
### JWT 的使用方式
客户端收到服务器返回的 JWT可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息 Authorization 字段里面。
```http
Authorization: Bearer <token>
```
### JWT 的认证流程图
![JWT 的认证流程图](https://static.7wate.com/img/2022/08/30/d6666d37094db.png)
### JWT 的优点
- 不需要在服务端保存会话信息RESTful API 的原则之一就是无状态),所以易于应用的扩展,即信息不保存在服务端,不会存在 Session 扩展不方便的情况。
- JWT 中的 Payload 负载可以存储常用信息,用于信息交换,有效地使用 JWT可以降低服务端查询数据库的次数。
### JWT 的缺点
- **加密问题:** JWT 默认是不加密,但也是可以加密的;生成原始 Token 以后,可以用密钥再加密一次。
- **到期问题:** 由于服务器不保存 Session 状态,因此无法在使用过程中废止某个 Token或者更改 Token 的权限。一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。

View File

@ -0,0 +1,220 @@
---
title: OAuth 鉴权
description: OAuth 鉴权
keywords:
- OAuth
- 鉴权
tags:
- 权限
sidebar_position: 6
author: 7Wate
date: 2022-08-31
---
## OAuth 2.0
OAuth 协议又有 1.0 和 2.0 两个版本2.0 版整个授权验证流程更简单更安全,也是目前最主要的用户身份验证和授权方式。
### OAuth 2.0 定义
**OAuth** 是一个开放标准,允许用户授权第三方网站(例如 CSDN、思否等获取用户数据。而不需要将用户名和密码提供给第三方网站常见的提供 OAuth 认证服务的厂商: **支付宝、QQ、微信、微博。**
简单说,**OAuth 就是一种授权机制。数据的所有者告诉系统同意授权第三方应用进入系统并获取这些数据。系统从而产生一个短期的进入令牌Token用来代替密码供第三方应用使用。**
#### 令牌与密码的差异
令牌Token与密码Password的作用是一样的都可以进入系统但是有三点差异。
1. **令牌是短期的,到期会自动失效,**用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
2. **令牌可以被数据所有者撤销,会立即失效。**
3. **令牌有权限范围scope** 对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。
OAuth 2.0 对于如何颁发令牌的细节,规定得非常详细。具体来说,一共分成**四种授权**模式 **Authorization Grant** ,适用于不同的互联网场景。
- 授权码authorization-code
- 隐藏式implicit
- 密码式password
- 客户端凭证client credentials
无论哪个模式都拥有三个必要角色:**客户端**、**授权服务器**、**资源服务器**,有的还有**用户(资源拥有者)**。
## 授权码模式
**授权码Authorization Code Grant) 方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。**
这种方式是最常用的流程,安全性也最高,它适用于那些有后端服务的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
一句话概括:**客户端换取授权码,客户端使用授权码换 Token客户端使用 Token 访问资源**。
### 步骤详解
#### 1. 客户端
打开网站 A点击登录按钮请求 A 服务A 服务重定向 (重定向地址如下) 至授权服务器如QQ、微信授权服务
```http
https://qq.com/oauth/authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read
```
上面 URL 中response_type 参数表示要求返回授权码codeclient_id 参数让 B 知道是谁在请求redirect_uri 参数是 B 接受或拒绝请求后的跳转网址scope 参数表示要求的授权范围(这里是只读)
![授权码模式](https://static.7wate.com/img/2022/08/30/cd507ff3bb9b9.png)
#### 2. 授权服务器
授权服务网站会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,这时授权服务网站就会跳回 redirect_uri 参数指定的网址。跳转时会传回一个授权码就像下面这样code 参数就是授权码。
```http
https://a.com/callback?code=AUTHORIZATION_CODE
```
![授权服务器](https://static.7wate.com/img/2022/08/30/e8a2a515684a0.png)
#### 3. 网站 A 服务器
拿到授权码以后,就可以向 授权服务器 (qq.com) 请求令牌。
```http
https://qq.com/oauth/token?
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=CALLBACK_URL
```
上面 URL 中client_id 参数和 client_secret 参数用来让授权服务器 确认 A 的身份client_secret 参数是保密的因此只能在后端发请求grant_type 参数的值是 AUTHORIZATION_CODE表示采用的授权方式是授权码code 参数是上一步拿到的授权码redirect_uri 参数是令牌颁发后的回调网址。
![网站 A 服务器](https://static.7wate.com/img/2022/08/30/f75bff03879bd.png)
#### 4. 授权服务器
收到请求以后,验证通过,就会颁发令牌;具体做法是向 redirect_uri 指定的网址,发送一段 JSON 数据。
```json
{
"access_token":"ACCESS_TOKEN",
"token_type":"bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
"uid":100101,
"info":{...}
}
```
上面 JSON 数据中access_token 字段就是令牌A 网站在后端拿到了,然后返回给客户端即可。
![授权服务器](https://static.7wate.com/img/2022/08/30/e8a7b64693d3c.png)
## 隐藏式模式Implicit Grant
有些 Web 应用是纯前端应用,没有后端;这时就不能用上面的方式了,必须将令牌储存在前端。
OAuth2.0 就规定了**第二种方式,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)"隐藏式"implicit**。
一句话概括:**客户端让用户登录授权服务器换 Token客户端使用 Token 访问资源。**
### 步骤详解
#### 1. 客户端
打开网站 A然后 A 网站提供一个链接,要求用户跳转到授权服务器,授权用户数据给 A 网站使用。
```http
https://qq.com/oauth/authorize?
response_type=token&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read
```
上面 URL 中response_type 参数为 token表示要求直接返回令牌。
#### 2. 授权服务器
用户跳转到授权服务器,登录后同意给予 A 网站授权。这时,授权服务器就会跳回 redirect_uri 参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。
```http
https://a.com/callback#token=ACCESS_TOKEN
```
上面 URL 中token 参数就是令牌A 网站因此直接在前端拿到令牌。
![授权服务器](https://static.7wate.com/img/2022/08/30/0e02abdb53ae8.png)
还有需要**注意**的地方如下:
1. 令牌的位置是 URL 锚点fragment而不是查询字符串querystring这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议,因此存在"中间人攻击"的风险,而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。
2. 这种方式把令牌直接传给前端是很不安全的。因此只能用于一些安全要求不高的场景并且令牌的有效期必须非常短通常就是会话期间session有效浏览器关掉令牌就失效了。
## 用户名密码式模式Password Credentials Grant
如果你高度信任某个应用OAuth 2.0 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"password
一句话概括:**用户在客户端提交账号密码换 Token客户端使用 Token访问资源。**
### 步骤详解
##### 1. 客户端
A 网站要求用户提供 授权服务器qq.com的用户名和密码。拿到以后A 就直接向授权服务器请求令牌。
```http
https://oauth.b.com/token?
grant_type=password&
username=USERNAME&
password=PASSWORD&
client_id=CLIENT_ID
```
上面 URL 中grant_type 参数是授权方式,这里的 password 表示"密码式"username 和 password 是授权服务器的用户名和密码。
##### 2. 授权服务器
授权服务器验证身份通过后,直接给出令牌。注意,这时不需要跳转,而是把令牌放在 JSON 数据里面,作为 HTTP 回应A 网站因此拿到令牌。
这种方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。
## 客户端模式Client Credentials Grant
客户端模式指客户端以自己的名义,而不是以用户的名义,向授权服务器进行认证。主要适用于没有前端的命令行应用。
一句话概括:**客户端使用自己的标识换token客户端使用token访问资源**。
### 步骤详解
##### 1. 客户端
客户端向授权服务器进行身份认证,并要求一个访问令牌。
```http
https://oauth.b.com/token?
grant_type=client_credentials&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET
```
上面 URL 中grant_type 参数等于 client_credentials 表示采用凭证式client_id 和 client_secret 用来让授权服务器确认 A 的身份。
##### 2. 授权服务器
授权服务器验证通过以后,直接返回令牌。这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。
## 授权模式对比
按授权需要的多端情况:
| 模式 | 需要前端 | 需要后端 | 需要用户响应 | 需要客户端密钥 |
| --------------------------------- | -------- | -------- | ------------ | -------------- |
| 授权码模式 Authorization Code | ✅ | ✅ | ✅ | ✅ |
| 隐式授权模式 Implicit Grant | ✅ | ❌ | ✅ | ❌ |
| 密码授权模式 Password Grant | ✅ | ✅ | ✅ | ✅ |
| 客户端授权模式 Client Credentials | ❌ | ✅ | ❌ | ✅ |
## 授权模式分类
![按照客户端类型与访问令牌所有者分类](https://static.7wate.com/img/2022/08/30/aa101efbae0a2.png)

View File

@ -0,0 +1,106 @@
---
title: Session-Cookie 鉴权
description: Session-Cookie 鉴权
keywords:
- Session
- Cookie
- 鉴权
tags:
- 权限
sidebar_position: 2
author: 7Wate
date: 2022-08-31
---
## Session-Cookie 鉴权
**Session-Cookie** 认证是利用服务端的 **Session会话**)和 **浏览器(客户端)** 的 Cookie 来实现的前后端通信认证模式。
在理解这句话之前我们先简单了解下**什么是 Cookie**以及**什么是 Session**
### Cookie 是什么
众所周知,**HTTP 是无状态的协议**(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息);所以为了让服务器区分不同的客户端,就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器,而这个状态可以通过 **Cookie** 去实现。
#### 特点
- Cookie 存储在客户端,可随意篡改,不安全。
- 有大小限制,最大为 4kb。
- 有数量限制,一般一个浏览器对于一个网站只能存不超过 20 个 Cookie浏览器一般只允许存放 300个 Cookie。
- Android 和 IOS 对 Cookie 支持性不好。
- Cookie 是不可跨域的,但是一级域名和二级域名是允许共享使用的(靠的是 domain
### Session 是什么
Session 的抽象概念是会话,是无状态协议通信过程中,为了实现中断 / 继续操作,将用户和服务器之间的交互进行的一种抽象;具体来说,是服务器生成的一种 Session 结构,可以通过多种方式保存,如内存、数据库、文件等,大型网站一般有专门的 Session 服务器集群来保存用户会话;
#### 流程
1. **客户端:** 用户向服务器首次发送请求。
2. **服务器:** 接收到数据并自动为该用户创建特定的 Session / Session ID来标识用户并跟踪用户当前的会话过程。
3. **客户端:** 浏览器收到响应获取会话信息,并且会在下一次请求时带上 Session / Session ID。
4. **服务器:** 服务器提取后会与本地保存的 Session ID进行对比找到该特定用户的会话进而获取会话状态。
5. 至此客户端与服务器的通信变成有状态的通信。
#### 特点
- Session 保存在服务器上。
- 通过服务器自带的加密协议进行。
### Session 与 Cookie 的差异
- **安全性:** Cookie 由于保存在客户端可随意篡改Session 则不同存储在服务器端,无法伪造。所以 Session 的安全性更高。
- **存取值的类型不同:** Cookie 只支持字符串数据Session 可以存任意数据类型。
- **有效期不同:** Cookie 可设置为长时间保持Session 一般失效时间较短。
- **存储大小不同:** Cookie 保存的数据不能超过 4K。
### Session-Cookie 的认证流程图
![Session-Cookie 的认证流程图](https://static.7wate.com/img/2022/08/30/50ad8c6cc6e96.png)
### Session-Cookie 认证步骤解析
1. **客户端:** 向服务器发送登录信息用户名 / 密码来请求登录校验。
2. **服务器:** 验证登录的信息,验证通过后自动创建 Session将 Session 保存在内存中,也可以保存在 Redis 中),然后给这个 Session 生成一个唯一的标识字符串会话身份凭证 session_id通常称为 sid并在响应头 Set-Cookie 中设置这个唯一标识符。
> 注:可以使用签名对 sid 进行加密处理,服务端会根据对应的 secret 密钥进行解密 (非必须步骤)
3. **客户端:** 收到服务器的响应后会解析响应头,并自动将 sid 保存在本地 Cookie 中,浏览器在下次 HTTP 请求时请求头会自动附带上该域名下的 Cookie 信息。
4. **服务器:** 接收客户端请求时会去解析请求头 Cookie 中的 sid然后根据这个 sid 去找服务端保存的该客户端的 sid然后判断该请求是否合法。
### Session-Cookie 的优点
- Cookie 简单易用。
- Session 数据存储在服务端,相较于 JWT 方便进行管理,也就是当用户登录和主动注销,只需要添加删除对应的 Session 就可以了,方便管理。
- 只需要后端操作即可,前端可以无感等进行操作。
### Session-Cookie 的缺点
- 依赖 Cookie一旦用户在浏览器端禁用 Cookie那么就 GG 思密达了。
- 非常不安全Cookie 将数据暴露在浏览器中,增加了数据被盗的风险(容易被 CSRF 等攻击)。
- Session 存储在服务端,增大了服务端的开销,用户量大的时候会大大降低服务器性能。
- 对移动端的支持性不友好。
### 使用场景
- 一般中大型的网站都适用(除了 APP 移动端)。
- 由于一般的 Session 需集中存储在内存服务器上(如 Redis这样就会增加服务器的预算所以预算不够请谨慎选择。

View File

@ -0,0 +1,85 @@
---
title: Token 鉴权
description: Token 鉴权
keywords:
- Token
- 鉴权
tags:
- 权限
sidebar_position: 3
author: 7Wate
date: 2022-08-31
---
## Token 鉴权
现在我们已经得知Session-Cookie 的一些缺点,以及 Session 的维护给服务端造成很大困扰,我们必须找地方存放它,又要考虑分布式的问题,甚至要单独为了它启用一套 Redis 集群。那有没有更好的办法?
于是 Token 就应运而生了
### Token令牌
Token 是一个令牌,客户端访问服务器时,验证通过后服务端会为其签发一张令牌,之后,客户端就可以携带令牌访问服务器,服务端只需要验证令牌的有效性即可。一句话概括:**访问资源接口API时所需要的资源凭证**
#### Token 的组成
一般 Token 的组成由 **uid** (用户唯一的身份标识)+ **time**(当前时间的时间戳) + **sign** 签名Token 的前几位以哈希算法压缩成的一定长度的十六进制字符串)
#### Token 的认证流程图
![Token 的认证流程图](https://static.7wate.com/img/2022/08/30/40b2dbfe8f84a.png)
#### Token 认证步骤解析
1. **客户端:** 输入用户名和密码请求登录校验。
2. **服务器:** 收到请求验证用户名与密码;验证成功后,服务端会签发一个 Token并把这个 Token 发送给客户端。
3. **客户端:** 收到 Token 以后需要把它存储起来Web 端一般会放在 localStorage 或 Cookie 中,移动端原生 APP 一般存储在本地缓存中。
4. **客户端:** 再次向服务端请求 API 资源的时候,将 Token 通过 HTTP 请求头 Authorization 字段或者其它方式发送给服务端。
5. **服务器:** 收到请求,然后去验证客户端请求里面带着的 Token 如果验证成功就向客户端返回请求的数据否则拒绝返还401
#### Token 的优点
- **服务端无状态化、可扩展性好:** Token 机制在服务端不需要存储会话Session信息因为 Token 自身包含了其所标识用户的相关信息,这有利于在多个服务间共享用户状态。
- **支持 APP 移动端设备。**
- **安全性好:** 有效避免 CSRF 攻击(因为不需要 Cookie
- **支持跨程序调用:** 因为 Cookie 是不允许跨域访问的,而 Token 则不存在这个问题。
#### Token 的缺点
- **配合:** 需要前后端配合处理。
- **占带宽:** 正常情况下比 sid 更大,消耗更多流量,挤占更多宽带。
- **性能问题:** 虽说验证 Token 时不用再去访问数据库或远程服务进行权限校验,但是需要对 Token 加解密等操作,所以会更耗性能。
- **有效期短:** 为了避免 Token 被盗用,一般 Token 的有效期会设置的较短,所以就有了 Refresh Token。
### Refresh Token刷新 Token
业务接口用来鉴权的 Token我们称之为 Access Token。为了安全我们的 Access Token 有效期一般设置较短,以避免被盗用。但过短的有效期会造成 Access Token 经常过期,过期后怎么办呢?
一种办法是**刷新 Access Token**,让用户重新登录获取新 Token会很麻烦。另一种办法是再来一个 Token一个专门生成 Access Token 的 Token我们称为 **Refresh Token**
- **Access Token** 用来访问业务接口,由于有效期足够短,盗用风险小,也可以使请求方式更宽松灵活;
- **Refresh Token** 用来获取 Access Token有效期可以长一些通过独立服务和严格的请求方式增加安全性由于不常验证也可以如前面的 Session 一样处理;
#### Refresh Token 的认证流程图
![Refresh Token 的认证流程图](https://static.7wate.com/img/2022/08/30/0f634bdff18ca.png)
#### Refresh Token 认证步骤解析
1. **客户端:** 输入用户名和密码请求登录校验。
2. **服务端:** 收到请求,验证用户名与密码;验证成功后,服务端会签发一个 Access Token 和 Refresh Token 并返回给客户端;
3. **客户端:** 把 Access Token 和 Refresh Token 存储在本地;
4. **客户端:** 请求数据时,携带 Access Token 传输给服务端;
5. **服务端**
- 验证 Access Token 有效:正常返回数据
- 验证 Access Token 过期:拒绝请求
6. **客户端** ( Access Token 已过期) **** 则重新传输 Refresh Token 给服务端;
7. **服务端** ( Access Token 已过期) **** 验证 Refresh Token ,验证成功后返回新的 Access Token 给客户端;
8. **客户端:** 重新携带新的 Access Token 请求接口;
### Token 和 Session-Cookie 的区别
Session-Cookie 和 Token 有很多类似的地方,但是 Token 更像是 Session-Cookie 的升级改良版。
- **存储地不同:** Session 一般是存储在服务端Token 是无状态的,一般由前端存储。
- **安全性不同:** Session 和 Token 并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重放攻击。
- **支持性不同:** Session-Cookie 认证需要靠浏览器的 Cookie 机制实现,如果遇到原生 NativeAPP 时这种机制就不起作用了,或是浏览器的 Cookie 存储功能被禁用,也是无法使用该认证机制实现鉴权的;而 Token 验证机制丰富了客户端类型。

View File

@ -0,0 +1,8 @@
{
"label": "鉴权解决方案",
"position": 3,
"link": {
"type": "generated-index",
"title": "鉴权解决方案"
}
}

View File

@ -0,0 +1,57 @@
---
title: 一键登录
description: 一键登录
keywords:
- 一键登录
- APP
tags:
- 权限
sidebar_position: 10
author: 7Wate
date: 2022-08-31
---
## 一键登录适用于原生APP
### 账号密码登录
大家都知道,最传统的登录方式就是使用**账号加密码登录**,简单粗暴,一般也不会出现什么问题;但这种方式的缺点如下:
1. 但这种方式要求用户要记住自己的账号和密码,也就是有一个记忆成本。用户为了降低记忆成本,很可能会在不同平台使用同一套账号密码。从安全角度考虑,一旦某个平台的账号密码泄露了,会连累到该用户使用的其他平台。
2. 另外,由于账号和个人身份无关,意味着同一个用户可以注册多个不同的账号,也就是可能会有恶意注册的情况发生。
**最后直到手机卡的强制实名制才得以解决!**
### 手机号验证码登录
随着无线互联的发展以及手机卡实名制的推广,手机号俨然已成为特别的身份证明,与账号密码相比,手机号可以更好地验证用户的身份,防止恶意注册。
但是手机号注册还是需要一系列繁琐的操作:输入手机号、等待短信验证码、输入验证码、点击登录。整个流程少说二十秒,而且如果收不到短信,也就登录不了,问题有可能导致潜在的用户流失。
从安全角度考虑,还存在验证码泄漏的风险。如果有人知道了你的手机号,并且窃取到了验证码,那他也能登录你的账号了。
**所以就有了一键登录操作!**
### 一键登录的定义
我们想一下,为什么我们需要验证码?验证码的作用就是确定这个手机号是你的,那除了使用短信,是否还有别的方式对手机号进行认证?于是,就有了咱们的主角**一键登录**。
短信验证码的作用:证明当前操作页面的用户与输入手机号的用户为相同的人,那么实际上只要我们能够获取到当前手机使用的手机卡号,直接使用这个号码进行登录,不需要额外的操作,这就是一键登录。
一键登录能不能做,取决于运营商是否开放相关服务;随着运营商开放了相关的服务,我们现在已经能够接入运营商提供的 SDK 并付费使用相关的服务。
### 一键登录流程图
![一键登录流程图](https://static.7wate.com/img/2022/08/30/855d4c809d739.png)
### 一键登录步骤详解
1. **SDK 初始化:** 调用 SDK 方法,传入平台配置的 AppKey 和 AppSecret
2. **唤起授权页:** 调用 SDK 唤起授权接口SDK 会先向运营商发起获取手机号掩码的请求,请求成功后跳到授权页。授权页会显示手机号掩码以及运营商协议给用户确认。
3. **同意授权并登录:** 用户同意相关协议点击授权页面的登录按钮SDK 会请求本次取号的 Token请求成功后将 Token 返回给客户端
4. **取号:** 将获取到的 Token 发送到自己的服务器,由服务端携带 Token 调用运营商一键登录的接口,调用成功就返回手机号码。服务端用手机号进行登录或注册操作,返回操作结果给客户端,完成一键登录。
**三大运营商开放平台:**[移动 - 互联网能力开放平台](http://dev.10086.cn/)、[电信 - 天翼账号开放平台](https://id.dlife.cn/)、[联通 - WO+ 开放平台](https://onlinebusiness.10010.com/?chnl=none)。
由于国内三大运营商各自有独立的 SDK所以会导致兼容方面的工作会特别繁琐。如果要采用一键登录的方案不妨采用第三方提供了号码认证服务下列几家供应商都拥有手机号码认证能力[阿里 - 号码认证服务](https://help.aliyun.com/product/75010.html)、[创蓝 - 闪验](http://shanyan.253.com/)、[极光 - 极光认证](https://www.jiguang.cn/identify)、[mob - 秒验](https://www.mob.com/mobService/secverify)
在认证过程中,需要用户打开蜂窝网络,如果手机设备没有插入 SIM 卡、或者关闭蜂窝网络的情况下,是无法完成认证的。所以就算接入一键登录,还是要兼容传统的登录方式,允许用户在失败的情况下,仍能正常完成登录流程。

View File

@ -0,0 +1,70 @@
---
title: SSO 单点登录
description: SSO 单点登录
keywords:
- 单点登录
- SSO
- Single Sign On
tags:
- 权限
sidebar_position: 5
author: 7Wate
date: 2022-08-31
---
## 单点登录Single Sign On
现在随着企业的发展,一个大型系统里可能包含 n 多子系统,用户在操作不同的系统时,需要多次登录,很麻烦,那么**单点登录SSO**就可以很好的解决这个问题的,在**多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统**。
例如登录天猫,淘宝也会自动登录;登录百度贴吧,百度网盘也会自动登录。
### 同域下的 SSO主域名相同
当百度网站存在两个相同主域名下的贴吧子系统 tieba.baidu.com 和网盘子系统 pan.baidu.com 时,以下为它们实现 SSO 的步骤:
1. **客户端:** 用户访问某个子系统时(例如 tieba.baidu.com如果没有登录则跳转至 SSO 认证中心提供的登录页面进行登录。
2. **服务端:** 登录认证后,服务端把登录用户的信息存储于 Session 中,并且附加在响应头的 Set-Cookie 字段中,设置 Cookie 的 Domain 为 .baidu.com
3. 客户端:再次发送请求时,携带主域名 Domain 下的 Cookie 给服务器,此时服务端就可以通过该 Cookie 来验证登录状态了;
### 跨域下的 SSO主域名不同
在我们常见的购物网站天猫tmall.com和 淘宝taobao.com我们只需要登录其中某一个系统另外一个系统打开后就会默认登录那么这是怎么做的呢
那么就有了 **CASCentral Authentication Service中央授权服务**,那么我们先主要说下 CAS 的流程。
#### 单点登录下的 CAS 认证流程图
![单点登录下的 CAS 认证流程图](https://static.7wate.com/img/2022/08/30/227748c758a02.png)
#### 单点登录下的 CAS 认证步骤详解
1. **客户端:** 访问系统 A。
2. **系统 A** 发现用户未登录,重定向至 CAS 认证服务sso.com同时 URL 地址参数携带登录成功后回跳到系统 A 的页面链接 `sso.com/login?redir…`
3. **CAS 认证服务:** 发现请求 Cookie 中没有携带登录的票据凭证TGC所以 CAS 认证服务判定用户处于**未登录状态**,重定向用户页面至 CAS 的登录界面,用户在 CAS 的登录页面上进行登录操作。
4. **客户端:** 输入用户名密码进行 CAS 系统认证;
5. **CAS 认证服务:** 校验用户信息,并且生成 TGC 放入自己的 Session 中,同时以 Set-Cookie 形式写入 Domain 为 sso.com 的域下 ;同时生成一个授权令牌 ST (Service Ticket),然后重定向至系统 A 的地址,重定向的地址中包含生成的 ST重定向地址 `www.taobao.com?token=ST-345678`
6. **系统 A** 拿着 ST 向 CAS 认证服务发送请求CAS 认证服务验证票据 (ST) 的有效性。验证成功后,系统 A 知道用户已经在 CAS 登录了(其中的 ST 可以保存到 Cookie 或者本地中),系统 A 服务器使用该票据 (ST) 创建与用户的会话,称为局部会话,返回受保护资源。
***到这里客户端就可以跟系统 A 愉快的交往啦 ~***
1. **客户端:** 开始访问系统 B。
2. **系统 B** 发现用户未登录,重定向至 SSO 认证服务,并将自己的地址作为参数传递,并附上在 sso.com 域下的 cookie 值是第五步生成的 TGC。
3. **CAS 认证服务:** CAS 认证服务中心发现用户已登录,跳转回系统 B 的地址,并附上票据 (ST) ;
4. **系统 B** 拿到票据 (ST),去 CAS 认证服务验证票据 (ST) 的有效性。验证成功后,客户端也可以跟系统 B 交往了 ~
#### 单点登录下需要注意的地方
如图中流程所示,我们发现 CAS 认证服务在签发的授权令牌 ST 后,直接重定向,这样其实是比较容易容易被窃取,那么我们需要在系统 A 或者系统 B 在向 CAS 验证成功 (如图中的第 14 步和第 11 步) 后,再生成另一个新的验证 Token 返回给客户端保存。
#### CAS 常用接口
- **login**:登录接口,用于登录到中央授权服务
- **logout**:登出接口,用于从中央授权服务中登出
- **validate**:用于验证用户是否登录中央授权服务
- **serviceValidate**:用于让各个 Service 验证用户是否登录中央授权服务
#### CAS 生成的票据
- **TGTTicket Grangting Ticket** TGT 是 CAS 为用户签发的登录票据,拥有了 TGT用户就可以证明自己在 CAS 成功登录过。
- **TGCTicket Granting Cookie** CAS Server 生成TGT放入自己的 Session 中,而 TGC 就是这个 Session 的唯一标识SessionId以 Cookie 形式放到浏览器端,是 CAS Server 用来明确用户身份的凭证。
- **STService Ticket** ST 是 CAS 为用户签发的访问某个 Service 的票据。

View File

@ -0,0 +1,38 @@
---
title: 唯一登录
description: 唯一登录
keywords:
- 唯一登录
tags:
- 权限
sidebar_position: 8
author: 7Wate
date: 2022-08-31
---
## 唯一登录
### 唯一登录定义
唯一登录是指**禁止多人同时登录同一账号,后者的登录行为,会导致前者掉线。**
通俗点讲就是A 账号在 A 电脑上登录后A 账号此时又用 B 电脑再次登录,则 A 电脑请求页面时,提示“重新登录”的信息,并跳转到登录页面
### 唯一登录流程图
![唯一登录流程图](https://static.7wate.com/img/2022/08/30/f71a772c45d73.png)
### 唯一登录步骤详解
#### 用户 - 客户端 A 操作
1. 输入账号请求登录接口。
2. 后端生成对应 Token 并且返回给客户端 A并且在服务端保存一个登录状态。
3. 客户端 A 保存 Token并且每次请求都在 header 头中携带对应的 Token。
#### 用户 - 客户端 B 操作
1. 输入账号请求登录接口。
2. ……
用户在客户端 B 上开始登录操作时我们会发现步骤和在客户端A上面的操作几乎是一致的。只是后端在生成新的 Token 时,要**先验证登录状态**,然后再生成对应新的 Token

View File

@ -0,0 +1,48 @@
---
title: 扫码登录
description: 扫码登录
keywords:
- 扫码登录
- 二维码
tags:
- 权限
sidebar_position: 9
author: 7Wate
date: 2022-08-31
---
## 扫码登录
### 扫码登录定义
扫码登录通常见于移动端 APP 中,很多 PC 端的网站都提供了扫码登录的功能,无需在网页上输入任何账号和密码,只需要让移动端 APP如微信、淘宝、QQ等等中已登录用户主动扫描二维码 ,再确认登录,以使 PC 端的同款应用得以快速登录的方式就是扫码登录 。
### 二维码定义
二维码又称二维条码,常见的二维码为 QR CodeQR 全称 Quick Response是一个近几年来移动设备上超流行的一种编码方式它比传统的 Bar Code 条形码能存更多的信息,也能表示更多的数据类型。
### 扫码登录的认证流程图
![扫码登录的认证流程图](https://static.7wate.com/img/2022/08/30/3a298ee5cc11d.png)
### 扫码登录的步骤详解
#### 1. 待扫码阶段
1. **桌面端:**打开某个网站如taobao.com或者某个 APP 的扫码登录入口;就会携带 PC 端的设备信息向服务端发送一个获取二维码的请求。
2. **服务端:**服务器收到请求后,随机生成一个 UUID 作为二维码 ID并将 UUID 与桌面端的设备信息关联起来存储在 Redis 服务器中,然后返回给 PC 端;同时设置一个过期时间,在过期后,用户登录二维码需要进行刷新重新获取。
3. **桌面端:**收到二维码 ID 之后,将二维码 ID 以二维码的形式展示,等待移动端扫码。并且此时的桌面端开始轮询查询二维码状态,直到登录成功。
4. 如果移动端未扫描,那么一段时间后二维码会自动失效。
#### 2. 已扫码待确认阶段
1. **移动端:**打开手机端对应已登录的 APP (微信或淘宝等),开始扫描识别桌面端展示的二维码;移动端扫描二维码后,会自动获取到二维码 ID并将移动端登录的信息凭证Token和二维码 ID 作为参数发送给服务端,此时手机必须是已登录(使用扫描登录的前提是移动端的应用为已登录状态,这样才可以共享登录态)。
2. **服务端:**收到手机端发来的请求后,会将 Token 与二维码 ID 关联为什么需要关联呢因为当我们在使用微信时移动端退出时PC 端也应该随之退出登录,这个关联就起到这个作用。然后会生成一个临时 Token这个 Token 会返回给移动端,一次性 Token 用作确认时的凭证。
#### 3. 已确认阶段
1. **移动端:**收到确认信息后,点击确认按钮,移动端携带上一步中获取的临时 Token 发送给服务端校验;
2. **服务端:**服务端校验完成后,会更新二维码状态,并且给 PC 端生成一个正式的 Token后续 PC 端就是持有这个 Token 访问服务端。
3. **桌面端:**轮询到二维码状态为已登录状态,并且会获取到了生成的 Token完成登录后续访问都基于 Token 完成。

View File

@ -0,0 +1,31 @@
---
title: 联合登录和信任登录
description: 联合登录和信任登录
keywords:
- 联合登录
- 信任登录
tags:
- 权限
sidebar_position: 7
author: 7Wate
date: 2022-08-31
---
## 联合登录和信任登录
### 联合登录定义
联合登录指同时包含多种凭证校验的登录服务,同时,也可以理解为使用第三方凭证进行校验的登录服务。
通俗点讲:**对于两个网站 A 和 B在登录 A 网站的时候用 B 网站的帐号密码,就是联合登录,或者登录 B 网站的时候使用 A 网站的帐号密码,也是联合登录。**
这样的概念其实与上面所讲的 OAuth2.0 的用户名密码式模式认证方式类似。最经典的莫过于 APP 内嵌 H5 的使用场景,当用户从 APP 进入内嵌的 H5 时,我们希望 APP 内已登录的用户能够访问到 H5 内受限的资源,而未登录的用户则需要登录后访问。
这里思路主要有两种,一种是原生跳转内嵌 H5 页面时,将登录态 Token 附加在 URL 参数上,另一种则是内嵌 H5 主动通过与原生客户端制定的协议获取应用内的登录状态。
### 信任登录定义
信任登录是指所有不需要用户主动参与的登录,例如建立在私有设备与用户之间的绑定关系,凭证就是私有设备的信息,此时不需要用户再提供额外的凭证。信任登录又指用第三方比较成熟的用户库来校验凭证,并登录当前访问的网站。
通俗点讲: **在 A 网站有登录状态的时候,可以直接跳转到 B 网站而不用登录,就是信任登录。**
目前比较常见的第三方信任登录帐号如QQ 号淘宝帐号、支付宝帐号、微博帐号等。我们不难发现 OAtuth 2.0 其实就是信任登录的缩影,因为正是有了 OAuth我们的信任登录才得以实现。