Skip to content

Commit 4b91691

Browse files
committed
2019.11.13
1 parent cdae1f9 commit 4b91691

2 files changed

Lines changed: 373 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
CORS 和 CSRF 这两个名字长得实在太像了!
2+
3+
千万别混淆了,看完本文,你就清楚了。
4+
5+
开始介绍:
6+
7+
## 一、CORS 和 CSRF 概念
8+
9+
先看下图:
10+
11+
![CORS 和 CSRF 概念](CORS-CSRF-1.png)
12+
13+
两者概念完全不同,另外常常我们也会一起看到一个叫 XSS ,这里也一起介绍一下:
14+
15+
1. **CSRF** : Cross-Site Request Forgery 跨站请求伪造
16+
17+
2. **CORS** : Cross Origin Resourse-Sharing 跨站资源共享
18+
19+
3. **XSS** : Cross Site Scrit 跨站脚本攻击(为与 CSS 区别,所以在安全领域叫 XSS)
20+
21+
## 二、CORS
22+
23+
> 跨来源资源共享(CORS),亦译为跨域资源共享,是一份浏览器技术的规范,提供了 Web 服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略,是 JSONP 模式的现代版。与 JSONP 不同,CORS 除了 GET 请求方法以外也支持其他的 HTTP 请求。用 CORS 可以让网页设计师用一般的 XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好。另一方面,JSONP 可以在不支持 CORS 的老旧浏览器上运作。现代的浏览器都支持 CORS。
24+
—— [维基百科](https://zh.wikipedia.org/wiki/%E8%B7%A8%E4%BE%86%E6%BA%90%E8%B3%87%E6%BA%90%E5%85%B1%E4%BA%AB)
25+
26+
27+
## 三、CSRF
28+
29+
> 跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。
30+
—— [维基百科](https://zh.wikipedia.org/wiki/%E8%B7%A8%E7%AB%99%E8%AF%B7%E6%B1%82%E4%BC%AA%E9%80%A0)
31+
32+
## 四、XSS
33+
34+
> 跨站脚本(英语:Cross-site scripting,通常简称为:XSS)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。
35+
—— [维基百科](https://zh.wikipedia.org/wiki/%E8%B7%A8%E7%B6%B2%E7%AB%99%E6%8C%87%E4%BB%A4%E7%A2%BC)
36+
37+
38+
39+
40+
## 参考文章
41+
42+
1. [《CSRF & CORS》](https://www.cnblogs.com/lailailai/p/4528092.html)
43+
2. [《跨站脚本攻击—XSS》](https://segmentfault.com/a/1190000020402185)
44+
3. [《前端安全系列(一):如何防止XSS攻击?》](https://tech.meituan.com/2018/09/27/fe-security.html)
Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
![cover](http://images.pingan8787.com/blog/Cover-OAuth2.png)
2+
3+
4+
## 一、OAuth 概念
5+
6+
> 开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。 —— 维基百科
7+
8+
严格来说,OAuth2 不是一个标准协议,而**是一个安全的授权框架**。其详细描述系统中不同角色,用户,服务前端应用(如 API )以及客户端(如网站或APP)之间如何**实现相互认证**
9+
10+
当前 OAuth 协议版本是 OAuth2.0,需要注意的是,OAuth2.0 并不向下兼容 OAuth1.0。
11+
12+
在生活中,比较常见的 OAuth2 的使用场景是**授权登录**,并且也广泛应用于 web、桌面应用和移动 APP 的**第三方服务提供授权登录验证机制,以实现不同应用直接数据访问的权限**
13+
14+
## 二、OAuth2 重点名词介绍
15+
16+
在 OAuth2 标准中定义了以下四种角色:
17+
18+
* 资源拥有者 (**Resource Owner**):
19+
20+
代表授权客户端访问本身资源信息的用户(User);
21+
22+
* 客户端 (**Client**):
23+
24+
代表意图访问受限资源的第三方应用。
25+
26+
* 资源服务器 (**Resource Server**):
27+
28+
代表托管了受保护的用户账号信息的服务器,它与认证服务器,可以是同一台服务器,也可以是不同的服务器;
29+
30+
31+
* 授权服务器 (**Authorization Server**):
32+
33+
代表验证用户身份然后为客户端派发资源访问令牌的服务器,即服务提供商专门用来处理认证的服务器;
34+
35+
## 三、OAuth2 运行流程
36+
37+
### 1. 流程分析
38+
39+
![20191028-OAuth2-01.png](http://images.pingan8787.com/blog/20191028-OAuth2-01.png)
40+
41+
(配图来自**阮一峰大佬**
42+
43+
大致流程概括就是:
44+
45+
* (A)Authrization Request
46+
47+
用户打开客户端以后,客户端要求用户给予授权。
48+
49+
* (B)Authorization Grant(Get)
50+
51+
用户同意给予客户端授权。
52+
53+
* (C)Authorization Grant(Post)
54+
55+
客户端向**授权服务器**发送它自己的客户端**身份标识**和上一步中获得的授权(authorization grant),向认证服务器申请令牌。
56+
57+
* (D)Access Token(Get)
58+
59+
认证服务器对客户端进行认证以后,确认无误,同意发放令牌(access token),授权阶段至此全部结束。
60+
61+
* (E)Access Token(Post && Validate)
62+
63+
客户端使用令牌,向资源服务器申请获取资源。
64+
65+
* (F)Protected Resource(Get)
66+
67+
资源服务器确认令牌无误,同意向客户端开放资源。
68+
69+
70+
理解完上面整个流程以后,我们再看看下面这张图,能更加清晰理解 OAuth2 的整个运行流程:
71+
72+
![20191028-OAuth2-02.png](http://images.pingan8787.com/blog/20191028-OAuth2-02.png)
73+
74+
(配图来自公众号**前端修仙之路**
75+
76+
从整个流程可以看出,在 B 步骤最为关键,即**需要获取到用户对客户端的授权**(如我们在微信扫码登录时,点击“确定”按钮的步骤)。
77+
78+
有了这个授权以后,客户端才能拿到令牌,进而凭令牌向资源服务器获取资源。
79+
80+
### 2. 案例:微信登录
81+
82+
另外,微信登录的实现流程也类似:
83+
84+
![20191028-OAuth2-03.png](http://images.pingan8787.com/blog/20191028-OAuth2-03.png)
85+
86+
(配图来自**微信官方文档**
87+
88+
其整体流程为:
89+
90+
1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会**拉起应用或重定向到第三方网站**,并且带上授权临时票据 `code` 参数;
91+
92+
2. 通过 `code` 参数加上 `AppID``AppSecret` 等,通过 API 换取 `access_token`
93+
94+
3. 通过 `access_token` 进行接口调用,**获取用户基本数据资源或帮助用户实现基本操作**
95+
96+
### 3. OAuth2 优缺点
97+
98+
* 优点:
99+
100+
适合快速开发实施,代码量少,API需要被不同APP使用,且每个APP使用方式也不同的情况。
101+
102+
* 缺点:
103+
104+
学习和理解的成本比较大,并且 OAuth2 不是一个严格的标准协议,在实施过程中更容易出错。
105+
106+
## 四、OAuth2 四种授权模式
107+
108+
通过前面描述,可以知道**OAuth 的核心就是向第三方应用颁发令牌。**
109+
110+
OAuth 2.0 规定了四种获得令牌的流程。你可以选择最适合自己的那一种,向第三方应用颁发令牌。即以下四种授权方式:
111+
112+
* 授权码(authorization-code)
113+
* 隐藏式(implicit)
114+
* 密码式(password)
115+
* 客户端凭证(client credentials)
116+
117+
**注意:**
118+
119+
不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:**客户端 ID(client ID)****客户端密钥(client secret)**
120+
121+
这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。
122+
123+
### 1. 授权码(authorization code)
124+
125+
**第三方应用先申请一个授权码,然后再用该码获取令牌**
126+
127+
适用于**有后端的 Web 应用**,授权码通过前端传送,**令牌则是储存在后端**,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
128+
129+
这种方式也是**最常用的流程,安全性最高**
130+
131+
#### 整体流程
132+
133+
![20191028-OAuth2-04.png](http://images.pingan8787.com/blog/20191028-OAuth2-04.png)
134+
135+
(配图来自**阮一峰大佬**
136+
137+
#### 步骤分析
138+
139+
1. 用户从 A 网站跳转到 B 网站,请求用户确认授权,以获取授权码,其发送链接示意如下:
140+
141+
```sh
142+
https://b.com/oauth/authorize?
143+
response_type=code&
144+
client_id=CLIENT_ID&
145+
redirect_uri=CALLBACK_URL&
146+
scope=read
147+
```
148+
其中:
149+
150+
`response_type` 参数表示要求返回授权码(code);
151+
152+
`client_id` 参数让 B 知道是谁在请求;
153+
154+
`redirect_uri` 参数是 B 接受或拒绝请求后的跳转网址;
155+
156+
`scope` 参数表示要求的授权范围(这里是只读);
157+
158+
2. 在 B 网站中,当用户同意授权 A 网站,则 B 网站会携带授权码,重定向到 `redirect_uri` 参数指定的网址,就像下面这样:
159+
160+
```sh
161+
https://a.com/callback?code=AUTHORIZATION_CODE
162+
```
163+
164+
3. A 网站获取授权码以后,在 A 网站后端中向 B 网站请求令牌:
165+
166+
```sh
167+
https://b.com/oauth/token?
168+
client_id=CLIENT_ID&
169+
client_secret=CLIENT_SECRET&
170+
grant_type=authorization_code&
171+
code=AUTHORIZATION_CODE&
172+
redirect_uri=CALLBACK_URL
173+
```
174+
175+
`client_id` 参数和 `client_secret` 参数用来让 B 确认 A 的身份( `client_secret` 参数是保密的,因此只能在后端发请求);
176+
177+
`grant_type` 参数的值是 `AUTHORIZATION_CODE` ,表示**采用的授权方式是授权码**;
178+
179+
`code` 参数是上一步拿到的授权码;
180+
181+
`redirect_uri` 参数是令牌颁发后的回调网址;
182+
183+
4. B 网站接受请求并验证身份,身份验证通过后,会发放令牌。向`redirect_uri` 指定的网址,发送包含令牌 `access_token` 字段的JSON数据,流程完毕。
184+
185+
### 2. 隐藏式(implicit)
186+
187+
**隐藏授权码步骤,直接向前端发放令牌**,也称授权码隐藏式。
188+
189+
#### 整体流程
190+
191+
![20191028-OAuth2-05.png](http://images.pingan8787.com/blog/20191028-OAuth2-05.png)
192+
193+
(配图来自**阮一峰大佬**
194+
195+
#### 步骤分析
196+
197+
1. 用户从 A 网站跳转到 B 网站,要求授权用户数据给 A 网站使用。
198+
199+
```sh
200+
https://b.com/oauth/authorize?
201+
response_type=token&
202+
client_id=CLIENT_ID&
203+
redirect_uri=CALLBACK_URL&
204+
scope=read
205+
```
206+
`response_type` 参数为 `token`,表示**要求直接返回令牌**
207+
208+
2. 用户在 B 网站同意授权给 A 网站。
209+
210+
当用户同意授权后,会跳转到 `redirect_uri` 参数指定的重定向地址,并将令牌作为 `URL` 参数传递给 A 网站。
211+
212+
```sh
213+
https://a.com/callback#token=ACCESS_TOKEN
214+
```
215+
216+
`token` 参数就是令牌,A 网站因此直接在前端拿到令牌。
217+
218+
**注意:**
219+
220+
这里的令牌位置是 `URL` 锚点(即 `#` 号),而不是查询字符串,这是因为锚点不会发到服务器,避免泄露令牌的风险。
221+
222+
**适用场景:**
223+
224+
由于直接传递令牌不安全,因此常常适用在对安全要求不高的场景,并且令牌有效期非常短,例如会话期间(session)有效,关闭浏览器便失效。
225+
226+
### 3. 密码式(password)
227+
228+
即:**对于信任的应用,可以携带约定的用户名和密码进行令牌申请**
229+
230+
#### 流程分析
231+
232+
![20191028-OAuth2-07.png](http://images.pingan8787.com/blog/20191028-OAuth2-07.png)
233+
234+
1. A 网站使用 B 网站提供的用户名和密码,向 B 网站发起令牌请求。
235+
236+
```sh
237+
https://oauth.b.com/token?
238+
grant_type=password&
239+
username=USERNAME&
240+
password=PASSWORD&
241+
client_id=CLIENT_ID
242+
```
243+
244+
`grant_type` 参数是授权方式,这里的 `password` 表示"密码式";
245+
`username``password` 是 B 的用户名和密码。
246+
247+
2. B 网站验证身份后直接将令牌存在 JSON 数据中,作为 HTTP 相应返回令牌给 A 网站。
248+
249+
**适用场景:**
250+
251+
风险较大,一般适用在对应用高度信任的情况。
252+
253+
### 4. 客户端凭证(client credentials)
254+
255+
即:**给出凭证让对方确认并提供令牌**
256+
257+
#### 流程分析
258+
259+
1. A 应用在命令行向 B 发出请求。
260+
261+
```sh
262+
https://oauth.b.com/token?
263+
grant_type=client_credentials&
264+
client_id=CLIENT_ID&
265+
client_secret=CLIENT_SECRET
266+
```
267+
268+
`grant_type` 参数等于 `client_credentials` 表示采用凭证式;
269+
`client_id``client_secret` 用来让 B 确认 A 的身份。
270+
271+
2. B 网站验证身份后返回令牌。
272+
273+
这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。
274+
275+
**适用场景:**
276+
277+
通过命令行请求令牌。
278+
279+
#### 流程分析
280+
281+
![20191028-OAuth2-06.png](http://images.pingan8787.com/blog/20191028-OAuth2-06.png)
282+
283+
## 五、使用令牌
284+
285+
当网站获取到令牌以后,接下来每个 API 请求都需要带上令牌,其做法是在请求的头信息中,将令牌添加 `Authorization` 字段中。
286+
287+
## 六、更新令牌
288+
289+
当令牌有效期到了,OAuth2 允许用户自动更新令牌,而不用让用户重新授权获取新令牌。
290+
291+
**具体流程:**
292+
293+
在 B 网站发放令牌时,一次性发放 2 个令牌,一个用于获取数据,一个用于获取新的令牌(`refresh token` 字段)。令牌到期后,用户使用 `refresh token` 发送请求去更新令牌:
294+
295+
```sh
296+
https://b.com/oauth/token?
297+
grant_type=refresh_token&
298+
client_id=CLIENT_ID&
299+
client_secret=CLIENT_SECRET&
300+
refresh_token=REFRESH_TOKEN
301+
```
302+
`grant_type` 参数为 `refresh_token` 表示要求更新令牌;
303+
`client_id` 参数和 `client_secret` 参数用于确认身份;
304+
`refresh_token` 参数就是用于更新令牌的令牌。
305+
306+
B 网站验证通过以后,就会颁发新的令牌。
307+
308+
## 参考文章
309+
310+
1. 部门内部培训资料
311+
2. [《OAuth 2 深入介绍》](https://www.cnblogs.com/Wddpct/p/8976480.html)
312+
3. [《阮一峰 理解OAuth 2.0》](www.ruanyifeng.com/blog/2014/05/oauth_2_0.html)
313+
4. [《阮一峰 OAuth 2.0 的四种方式》](www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html)
314+
315+
316+
### 关于我
317+
318+
> 本文首发在 [pingan8787个人博客](http://www.pingan8787.com),如需转载请联系本人。
319+
320+
|Author|王平安|
321+
|---|---|
322+
|E-mail|pingan8787@qq.com|
323+
|博 客|www.pingan8787.com|
324+
|微 信|pingan8787|
325+
|每日文章推荐|https://github.com/pingan8787/Leo_Reading/issues|
326+
|ES小册|js.pingan8787.com|
327+
328+
### 微信公众号
329+
![bg](http://images.pingan8787.com/blog/2019_10_24guild_page.png)

0 commit comments

Comments
 (0)