Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(apigw_manager/drf): update to support multiple stages #196

Merged
merged 6 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions sdks/apigw-manager/docs/jwt-explain.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# jwt 说明

后端服务接入网关时, 接口可能开启了应用认证/用户认证, 此时调用方需要传认证header头 `X-Bkapi-Authorization`, 网关认证通过后, 会生成一个 `X-Bkapi-JWT` 头给到后端服务, 里面包含了认证结果信息, 这是一个 jwt token
后端服务接入网关时接口可能开启了应用认证/用户认证,此时调用方需要传认证 header 头 `X-Bkapi-Authorization`, 网关认证通过后会生成一个 `X-Bkapi-JWT` 头给到后端服务里面包含了认证结果信息这是一个 jwt token

![img](./images/jwt.png)

## 如何获取网关公钥
## 1. 如何获取网关公钥

后端服务如需解析 API 网关发送的请求头 X-Bkapi-JWT,需要提前获取该网关的公钥。获取网关公钥,有以下方案。

### 1. 根据 SDK 提供的 Django Command 拉取
### 1.1 根据 SDK 提供的 Django Command 拉取

在同步网关数据时,直接添加以下 Command 拉取网关公钥。网关公钥将保存在 model Context 对应的库表 apigw_manager_context 中,SDK 提供的 Django 中间件将从表中读取网关公钥。

Expand All @@ -20,14 +20,14 @@ python manage.py fetch_apigw_public_key
python manage.py fetch_apigw_public_key --gateway-name my-gateway
```

### 2. 直接获取网关公钥,配置到项目配置文件
### 1.2 直接获取网关公钥,配置到项目配置文件

服务仅需接入一些固定的网关部署环境时,可在网关管理端,网关基本信息中查询网关公钥,并配置到项目配置文件。

蓝鲸官方网关,需要自动注册并获取网关公钥,可联系蓝鲸官方运营同学,在服务部署前,由官方提前创建网关,并设置网关公钥、私钥,同时将网关公钥同步给后端服务。
具体可参考 helm-charts 仓库的 README。

### 3. 通过网关公开接口,拉取网关公钥
### 1.3 通过网关公开接口,拉取网关公钥

API 网关提供了公钥查询接口,后端服务可按需根据接口拉取网关公钥,接口信息如下:

Expand All @@ -53,9 +53,9 @@ curl -X GET 'https://bkapi.example.com/api/bk-apigateway/prod/api/v1/apis/{gatew

- 拉取公钥时,不能实时拉取,需要添加缓存(实时拉取会导致整体接口性能下降)

## 校验请求来自 API 网关
## 2. 校验请求来自 API 网关

### 场景一:Django 项目
### 2.1 场景一:Django 项目

要在后端服务中认证 API 网关传递过来的请求头 `X-Bkapi-JWT`,可以通过在 settings 中的 MIDDLEWARE 中添加以下 Django 中间件。这样,在请求处理过程中,会自动解析请求头中的 X-Bkapi-JWT,并将相关信息添加到 request 对象中。

Expand Down Expand Up @@ -86,7 +86,7 @@ AUTHENTICATION_BACKENDS += [

- SDK model Context (库表 apigw_manager_context),需提前执行 `python manage.py fetch_apigw_public_key` 拉取并保存网关公钥

- settings.APIGW_PUBLIC_KEY,可在网关基本页面/API公钥通过点击`复制`按钮或者`下载`获取公钥,并配置到 settings 中。
- settings.APIGW_PUBLIC_KEY,可在网关基本页面/API 公钥通过点击`复制`按钮或者`下载`获取公钥,并配置到 settings 中。

> 公钥示例:
> ```shell
Expand All @@ -113,7 +113,7 @@ AUTHENTICATION_BACKENDS += [

##### ApiGatewayJWTUserMiddleware

根据 `request.jwt`,在 `request` 中注入 `user` 对象:
根据 `request.jwt`,在 `request` 中注入 `user` 对象

- 如果用户通过认证:其为一个 Django User Model 对象,用户名为当前请求用户的用户名
- 如果用户未通过认证,其为一个 Django AnonymousUser 对象,用户名为当前请求用户的用户名
Expand Down Expand Up @@ -157,7 +157,7 @@ APIGW_MANAGER_DUMMY_PAYLOAD_APP_CODE # JWT payload 中的 app_code
APIGW_MANAGER_DUMMY_PAYLOAD_USERNAME # JWT payload 中的 username
```

### 场景二:非 Django 项目
### 2.2 场景二:非 Django 项目

非 Django 项目,需要项目获取网关公钥,并解析请求头中的 X-Bkapi-JWT;获取网关公钥的方案请参考上文。

Expand Down Expand Up @@ -188,4 +188,4 @@ APIGW_MANAGER_DUMMY_PAYLOAD_USERNAME # JWT payload 中的 username
"nbf": 1701399303, # Not Before 时间
"iss": "APIGW" # 签发者
}
```
```
33 changes: 21 additions & 12 deletions sdks/apigw-manager/docs/plugin-use-guide.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# 插件配置说明

插件配置支持主要在 `stage`(definition.yaml) 和 `resource`(resource.yaml) 两个维度上,资源配置的插件优先级最高。
> 注意:所有配置均以 yaml 配置同步为主,举例来说: 如果通过yaml配置的插件配置则会覆盖掉用户在网关管理页面创建的插件配置,如果 yaml 没有配置该插件,则也不会移除
> 用户之前在页面创建的插件配置,不过 yaml 如果没有配置上一次yaml配置的插件,则会移除上一次 yaml 配置的插件。
> `CORS` 插件和 `IP 访问保护插件` 不推荐在yaml配置绑定在环境上。
> 注意:所有配置均以 yaml 配置同步为主,举例来说:如果通过 yaml 配置的插件配置则会覆盖掉用户在网关管理页面创建的插件配置,如果 yaml 没有配置该插件,则也不会移除
> 用户之前在页面创建的插件配置,不过 yaml 如果没有配置上一次 yaml 配置的插件,则会移除上一次 yaml 配置的插件。
> `CORS` 插件和 `IP 访问保护插件` 不推荐在 yaml 配置绑定在环境上。

## 1. 跨域资源共享(CORS)插件

## 跨域资源共享(CORS)插件
### 1.1 参数说明

| 参数 | 类型 | 默认值 | 描述 |
| ---------------- | ------ | ------ | ------------------------------------------------------------ |
Expand All @@ -15,7 +18,7 @@
| max_age | 整数 | 86400 | 浏览器缓存 CORS 结果的最大时间,单位为秒。 |
| allow_credential | 布尔值 | true | 是否允许跨域访问的请求方携带凭据(如 Cookie 等)。 |

### 配置例子
### 1.2 配置例子

```yaml
- type: bk-cors
Expand All @@ -28,14 +31,16 @@
allow_credential: false
```

## Header 转换插件
## 2. Header 转换插件

### 2.1 参数说明

| 参数 | 类型 | 默认值 | 描述 |
| ------ | ---- | ------ | ---------------------------- |
| set | 数组 | [] | 设置的请求头,包括键和值。 |
| remove | 数组 | [] | 删除的请求头,只需要提供键。 |

### 配置例子
### 2.2 配置例子

```yaml
- type: bk-header-rewrite
Expand All @@ -46,15 +51,17 @@
remove: []
```

## IP 访问保护插件
## 3. IP 访问保护插件

### 3.1 参数说明

| 参数 | 类型 | 默认值 | 描述 |
| --------- | ------ | ------ | -------------------------------------- |
| whitelist | 字符串 | "" | 白名单中的 IP 地址,支持 CIDR 表示法。 |
| blacklist | 字符串 | "" | 黑名单中的 IP 地址,支持 CIDR 表示法。 |
| message | 字符串 | "" | 当 IP 地址不被允许时显示的消息。 |

### 配置例子
### 3.2 配置例子

```yaml
- type: bk-ip-restriction
Expand All @@ -64,16 +71,18 @@
message: 'Your IP is not allowed'
```

## 频率控制插件
## 4. 频率控制插件

### 4.1 参数说明

| 参数 | 类型 | 默认值 | 描述 |
| ----------- | ------ | ------ | ------------------------------------------------ |
| rates | 对象 | {} | 包含默认频率限制和特殊应用频率限制的对象。 |
| default | 对象 | {} | 单个应用的默认频率限制,包括次数和时间范围。 |
| specials | 数组 | [] | 特殊应用频率限制,对指定应用设置单独的频率限制。 |
| bk_app_code | 字符串 | "" | 蓝鲸应用ID,用于特殊应用频率限制。 |
| bk_app_code | 字符串 | "" | 蓝鲸应用 ID,用于特殊应用频率限制。 |

### 配置例子
### 4.2 配置例子

```yaml
- type: bk-rate-limit
Expand Down
26 changes: 15 additions & 11 deletions sdks/apigw-manager/docs/sync-apigateway-with-django.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
### 直接使用 Django Command 同步网关
# 直接使用 Django Command 同步网关

项目安装 SDK apigw-manager 后,可以直接执行 SDK 提供的 Django Command。

- 准备文件的样例 [examples/django/use-custom-script](../examples/django/use-custom-script)

#### 步骤1. 准备自定义同步脚本
## 步骤 1. 准备自定义同步脚本

创建一个 bash 脚本,如 `sync-apigateway.sh`,使用 SDK 提供的 Django Command 定义网关配置的同步脚本,样例如下:

```shell
#!/bin/bash

Expand All @@ -31,7 +33,7 @@ python manage.py sync_apigw_config --gateway-name=${gateway_name} --file="${defi
python manage.py sync_apigw_stage --gateway-name=${gateway_name} --file="${definition_file}"

# 同步网关资源
#
#
# --delete: 当资源在服务端存在,却未出现在资源定义文件中时,指定本参数会强制删除这类资源,以保证服务端资源和文件内容完全一致。
# 如果未指定本参数,将忽略未出现的资源
# --doc_language: en/zh 是否生成接口文档(中文/英文)
Expand All @@ -54,6 +56,7 @@ echo "gateway sync definition end"
```

如果需要更灵活的控制,也可以采用自定义 Django Command 的方案,例如:

```python
from django.conf import settings
from django.core.management.base import BaseCommand
Expand All @@ -64,7 +67,7 @@ class Command(BaseCommand):
def handle(self, *args, **kwargs):
if not getattr(settings, "SYNC_APIGATEWAY_ENABLED", True):
return

# 待同步网关名,需修改为实际网关名;直接指定网关名,则不需要配置 Django settings BK_APIGW_NAME
gateway_name = "bk-demo"

Expand All @@ -81,15 +84,15 @@ class Command(BaseCommand):
call_command("fetch_apigw_public_key", f"--gateway-name={gateway_name}")
```

#### 步骤2. 添加 SDK apigw-manager
## 步骤 2. 添加 SDK apigw-manager

将 SDK apigw-manager 添加到项目依赖中,如 pyproject.toml 或 requirements.txt。

#### 步骤3. 将准备的网关配置文件,添加到项目
## 步骤 3. 将准备的网关配置文件,添加到项目

将准备的网关配置文件:definition.yaml, resources.yaml, apidocs (可选),添加到项目

#### 步骤4. 更新 Django settings 配置
## 步骤 4. 更新 Django settings 配置

在 Django settings.py 中定义网关名称和接口地址模板:

Expand All @@ -104,7 +107,7 @@ BK_APIGW_NAME = "my-gateway-name"
# 需将 bkapi.example.com 替换为真实的云 API 域名;
# 在 PaaS 3.0 部署的应用,可从环境变量中获取 BK_API_URL_TMPL,不需要额外配置;
# 实际上,SDK 将调用网关 bk-apigateway 接口将数据同步到 API 网关
BK_API_URL_TMPL = "http://bkapi.example.com/api/{api_name}/" ## 例如:网关host是:`bkapi.example.com`,则对应的值为:http://bkapi.example.com/api/{api_name} 注意:{api_name} 这个是占位符。
BK_API_URL_TMPL = "http://bkapi.example.com/api/{api_name}/" ## 例如:网关 host 是:`bkapi.example.com`,则对应的值为:http://bkapi.example.com/api/{api_name} 注意:{api_name} 这个是占位符。
```

在 INSTALLED_APPS 中加入以下配置,SDK 将创建表 `apigw_manager_context` 用于存储一些中间数据:
Expand All @@ -115,9 +118,10 @@ INSTALLED_APPS += [
]
```

#### 步骤5. 同步网关数据到 API 网关
## 步骤 5. 同步网关数据到 API 网关

chart 部署方案,可采用 K8S Job 同步,样例如下:

```yaml
apiVersion: batch/v1
kind: Job
Expand All @@ -140,12 +144,12 @@ spec:
```

二进制部署方案,在部署阶段直接执行 sync-apigateway.sh 脚本:

```shell
bash support-files/bin/sync-apigateway.sh
```


### 支持的 Django Command 列表
## 支持的 Django Command 列表

```bash
# 可选,为网关添加关联应用,关联应用可以通过网关 bk-apigateway 提供的接口管理网关数据
Expand Down
Loading
Loading