# API网关设计

**非原创**

## API所需安全功能 <a href="#api_1" id="api_1"></a>

### 身份和访问控制 <a href="#id-1" id="id-1"></a>

* **认证**

```
HTTP Basic：
API Key：客户端传递（参数+Key+Sign）到服务端（使用参数计算Sign，比较两个Sign）
OAuth：最受欢迎的网关验证协议
JWT：
```

* **授权**

```
RBAC：基于角色的访问控制
ABAC：基于属性的访问控制
```

### 通信安全 <a href="#id-2" id="id-2"></a>

### 威胁防护 <a href="#id-3" id="id-3"></a>

* **输入控制**
* **消息限制**
* **SQL注入**
* **JSON防护**
* **XML防护**
* **输出控制**

```
输出编码
```

### 日志记录 <a href="#id-4" id="id-4"></a>

```
认证日志：
操作日志：
```

### 黑白名单 <a href="#id-5" id="id-5"></a>

### API监控 <a href="#api_2" id="api_2"></a>

### API限速 <a href="#api_3" id="api_3"></a>

## API接口调用方式 <a href="#api_4" id="api_4"></a>

### HTTP+请求签名机制 <a href="#http" id="http"></a>

* **特点**

> 所有携带接口信息的HTTP头内容都必须参与签名计算
>
> 不同HTTP头内容也需要按照一定规则排序

* **优点**
* **缺点**

> 签名算法太复杂，易用性贼差
>
> 响应包可被窃听、伪造、需要防范Replay（重放）攻击

### HTTP+参数签名机制 <a href="#http_1" id="http_1"></a>

* **特点**

> 只有GET和POST参数的内容需要参与签名计算

* **优点**

> 签名算法想对简单，易用性有较大提升

* **缺点**

> 响应包可被窃听、伪造、需要防范Replay（重放）攻击

### HTTPS+访问令牌机制 <a href="#https" id="https"></a>

* **特点**

> 无需签名计算
>
> 依靠传输层加密和访问令牌的不可伪造性保证安全

* **优点**

> 相对安全，无法通过网络抓包方式窃听或伪造数据
>
> 易用性高，无需再为签名头疼，无需考虑Replay攻击

* **缺点**

> 安全性建立在用户不被中间人攻击和令牌不被泄漏的情况下

### 更好的方案 <a href="#id-6" id="id-6"></a>

* **牺牲易用性换取安全性**

> HTTPS+内容签名机制
>
> HTTPS+内容加密机制

* **降低令牌泄漏带来的风险**

> 为开发者提供绑定服务器IP列表、限制refer等支持
>
> 针对不同应用场景颁发不同有效期等访问令牌
>
> 针对不同安全级别的数据授权颁发不同有效期的访问令牌
>
> 为开发者和用户提供令牌作废支持

## 关于认证 <a href="#id-7" id="id-7"></a>

### JWT <a href="#jwt" id="jwt"></a>

JWT：Json Web Token 跨域认证解决方案

* **JWT数据格式**

以一个很长的字符串代表，中间用.分割成三个部分

```
Header.Payload.Signature
Header：头部
    alg：签名算法（algorithm），默认是HMAC SHA256；
    typ：表示令牌（token）的类型，JWT令牌统一为JWT；

Payload：负载（默认字段有以下7个，还可以自定义字段）
    iss（issuer）：签发人
    exp（expiration）：过期时间
    sub（subject）：主题
    aud（audience）：受众
    nbf（Not Before）：生效时间
    iat（Issued At）：签发时间
    jti（JWT ID）：编号

Signature：签名（指定一个密钥）
    sign=HMACSHA256（base64UrlEncode(header)+"."+baseUrlEncode(payload),secret）
```

关于Base64URL

```
=：被省略
+：替换为-
/：替换为_
```

* **JWT特点**

```
默认不加密，但是也可以加密；

JWT不加密的情况下，不能将敏感数据写入JWT；

JWT不仅可以用于认证，还可以用于交换信息；

JWT的缺点：由于服务器不保存session状态，因此无法在使用过程中废止某个token，或者更改token的权限。也就是说JWT一旦签发，到过期之前都有效；

JWT本身包含了认证信息，一旦泄漏，任何人都可以获得该令牌的所有权限。应该将有效期设置的短一些；

为了减少盗用JWT，应该尽可能使用HTTPS协议传输；
```

### OAuth <a href="#oauth" id="oauth"></a>

## 参考资料 <a href="#id-8" id="id-8"></a>

[网关在API安全中的作用](https://www.itcodemonkey.com/article/8515.html)

[REST API 安全设计指南](http://blog.nsfocus.net/rest-api-design-safety/)

[HTTP API接口安全设计](https://www.cnblogs.com/wintersun/p/6155255.html)

[开发安全的 API 所需要核对的清单](https://github.com/shieldfy/API-Security-Checklist/blob/master/README-zh.md)

[移动APP网关安全设计](https://www.jianshu.com/p/cd7d48b7af96)

[JSON Web Token 入门教程](http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html)

[理解OAuth2.0](http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html)
