# OAuth & JWT
###### tags: `觀念`
:::spoiler 目錄
[TOC]
:::
## OAuth
### 關於 Open Authorization
是一種**授權**給第三方服務的開放標準,
在使用者不提供密碼的情況下,令第三方服務可以存取使用者(特定範圍內)的帳戶資訊
### 歷史
* 2006: Twitter 的開發者首倡
* 2007: OAuth Core 1.0
* 2010: OAuth 1.0 Protocol 協定
* 2012: OAuth 2.0 Framework 框架
* 特點:授權流程標準化,提高安全性並得到廣泛採用(如fb google)
OAuth2.0 與 1.0 互不相容,在2.0框架中可以包涵很多協定來做規範
### 抽象概念流程圖
```
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
Figure 1: Abstract Protocol Flow
```
#### 角色解說
| 角色 | 說明 | 比如 |
| -------- | -------- | -------- |
| Resource Owner | 資源擁有者 | 擁有fb帳號的你我 |
| Resource Server | 資源伺服器 | 掌握使用者資料的fb |
| Client | 用戶端(第三方服務) | 需要存取你fb資料作為資源的程式 |
| Authorization Server | 授權伺服器 | fb的獨立授權伺服器 |
#### 流程解說
**A** . 用戶端向資源擁有者請求授權
**B** . 資源擁有者授權用戶端可以去取得 Access Token 來存取受保護資源
**C** . 用戶端要認證自己並出示 Authorization Grant 來向授權伺服器換取 Access Token
**D** . 授權伺服器認證用戶端並驗證 Authorization Grant,
. . . 如果都合法,就核發 Access Token
**E** . 用戶端出示 Access Token 向資源伺服器請求 Protected Resource
**F** . 資源伺服器驗證 Access Token ,如果合法就處理該請求
#### Refresh Token
* 如現有的 Access Token 過期而無效或是權限不足,需要再次取得 Token 時,就可以拿取 Refresh Token 向授權伺服器換新的 Access Token
* 不需要再次經過使用者的授權
* 若授權伺服器選擇可核發 Refresh Token ,必須在核發 Access Token 時一併核發
* 新的 Access Token 時效和權限可能會比之前的少
* Refresh Token 不應該被提交到資源伺服器端
```
+--------+ +---------------+
| |--(A)------- Authorization Grant --------->| |
| | | |
| |<-(B)----------- Access Token -------------| |
| | & Refresh Token | |
| | | |
| | +----------+ | |
| |--(C)---- Access Token ---->| | | |
| | | | | |
| |<-(D)- Protected Resource --| Resource | | Authorization |
| Client | | Server | | Server |
| |--(E)---- Access Token ---->| | | |
| | | | | |
| |<-(F)- Invalid Token Error -| | | |
| | +----------+ | |
| | | |
| |--(G)----------- Refresh Token ----------->| |
| | | |
| |<-(H)----------- Access Token -------------| |
+--------+ & Optional Refresh Token +---------------+
Figure 2: Refreshing an Expired Access Token
```
### 核發流程 Grant Type Flow
1. Authorization Code
1. Implicit
1. Password Credentials
1. Client Credentials
### (補充)HTTP 認證出示 token 的三種方式
1. 放在 Header 裡
```
Authorization: <type> <credentials>
```

2. 放在 Request Body 裡
用表單POST

3. 放在 URL 裡
ex. 中央氣象局api
### Bearer Token
#### 解釋
一種協定([RFC 6750](https://tools.ietf.org/html/rfc6750))用來搭配OAuth2.0傳輸,示範了一種向資源端傳輸 Access Token 的方法
#### 用法
```php
Authorization: Bearer + base64(code) //in header
```
### OAuth vs. OpenID Connect
兩者的機制大致相同
* OAuth 的目的是**授權**(Authorization)
* OIDC 目的是**認證**(Authentication)
## JWT
是一種符合 Stateless 之產生token的方法,可**以 Bearer 做傳送**
用於認證(如類似Session使用者認證)、授權以及資料交換
### 結構
分為三個部分 `header` / `payload` / `signature`
#### header
* JSON 格式
* 定義 Token 種類
* 定義其雜湊演算法
```php
{
“alg” : “HS256” //對稱式加密
“typ” : “JWT”
}
```
#### payload
* JSON 格式
* 放置所要傳達的資訊
* 放置 registered claims
* iss:發行方
* aud:預期接收者
* sub:聲明用於特定應用程序
* iat:發行時間
* exp:到期時間(以UNIX時間格式載)
```
{
“id” : “1”
“name” : “Esther”
“exp” : 1601979022
}
```
切勿放置隱私資訊於其中,因base64編碼能夠被輕易地轉換出來
#### signature
* 經由 Header 中所載之演算法處理
```php
HMACSHA256(
base64Encode(header) + "." +
base64Encode(payload),
"256-bit-secret key" //可先base64處理
)
```
### 組成
以 "." 分割成三個部分的字串

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpZCI6IjEiLCJuYW1lIjoiRXN0aGVyIiwiaXNzIjoidGVzdC5teXNlbGYiLCJleHAiOjE2MDE5NzkwMjJ9.
Xv6AoLX-36GJv_hSobM8_iOCxQxfFTmZFmXGLnYxbRY
```
分別代表 base64(header + payload) + signature
:::info
除非知道密鑰值,否則若直接修改payload內容,會在與signature驗證時因不一致被擋下來。
:::
### JWS (簽章) vs. JWE (加密)
若使用非對稱式加密
隨著公私鑰持有方的不同,數據的流動方向和方式就分為了兩種

[參考資料](https://5xruby.tw/posts/what-is-jwt/)
### 使用者驗證的比較
#### JWT 驗證

* 優點:伺服器不需花費Session成本
* 缺點:失去對使用者的掌控權,無法隨時註銷某用戶直到其token過期
#### Cookie-based session 驗證

* 優點:資料方便統一管理
* 缺點:Cookie 易被竄改、資料庫成本隨著用戶增加提高,每次驗證需經資料庫查詢耗費效能
### 參考資料
[1] [OWASP Top 10 Security Risks & Vulnerabilities](https://sucuri.net/guides/owasp-top-10-security-vulnerabilities-2020/)
[2] [開發者必備知識 - HTTP認證(HTTP Authentication)](https://carsonwah.github.io/http-authentication.html)