Files
iam-service/LOCAL_E2E_RUNBOOK.md
2026-02-03 10:17:11 +08:00

212 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 本地端到端联调iam-service + cms-service
目标:
- 生成临时 RSA 公私钥供 iam-service 使用RS256
- 启动 iam-service签发 token、发布 JWKS、提供权限裁决 `/authorize/check`
- 启动 cms-service本地验签 + 调用 IAM 做权限裁决)
- 在两个服务的 Scalar 页面完成:创建租户 → 注册用户 → 登录 → 调用 CMS 资源接口,验证“认证/权限由 IAM 控制”
> 本文不要求修改任何业务代码;只需要本地导出环境变量或创建 `.env` 文件。
## 0. 前置条件
- Rust支持 edition 2024与 Cargo
- PostgreSQL本机或 Docker并可使用 `psql`
- `openssl`
端口默认:
- iam-service3000
- cms-service3100
## 1. 准备数据库推荐Docker 一键起 PostgreSQL
启动 PostgreSQL
```bash
docker run --rm -d --name local-pg \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
postgres:16
```
创建 iam/cms 两个数据库与用户(示例账号,可按需调整):
```bash
docker exec -i local-pg psql -U postgres <<'SQL'
CREATE USER iam_service_user WITH PASSWORD 'iam_service_password';
CREATE DATABASE iam_service_db OWNER iam_service_user;
GRANT ALL PRIVILEGES ON DATABASE iam_service_db TO iam_service_user;
CREATE USER cms_service_user WITH PASSWORD 'cms_service_password';
CREATE DATABASE cms_service_db OWNER cms_service_user;
GRANT ALL PRIVILEGES ON DATABASE cms_service_db TO cms_service_user;
SQL
```
准备连接串(后续会分别用于两服务):
- IAM`postgres://iam_service_user:iam_service_password@127.0.0.1:5432/iam_service_db`
- CMS`postgres://cms_service_user:cms_service_password@127.0.0.1:5432/cms_service_db`
## 2. 生成临时 RSA 公私钥RS256
```bash
KEY_DIR="$(mktemp -d)"
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out "$KEY_DIR/jwt_private_key.pem"
openssl pkey -in "$KEY_DIR/jwt_private_key.pem" -pubout -out "$KEY_DIR/jwt_public_key.pem"
chmod 600 "$KEY_DIR/jwt_private_key.pem"
chmod 644 "$KEY_DIR/jwt_public_key.pem"
echo "KEY_DIR=$KEY_DIR"
```
说明:
- 私钥PKCS#8 PEM`BEGIN PRIVATE KEY`
- 公钥PKCS#8 公钥 PEM`BEGIN PUBLIC KEY`
- 该目录是临时目录,重启/清理后会消失;适合本地联调
## 3. 启动 iam-service签发 token + JWKS + 权限裁决)
在一个终端中执行(建议在 `iam-service` 目录下):
```bash
cd /home/shay/project/backend/iam-service
export PORT=3000
export DATABASE_URL='postgres://iam_service_user:iam_service_password@127.0.0.1:5432/iam_service_db'
# 用于 refresh token 指纹(不是 JWT 签名密钥),本地随便填一个即可
export JWT_SECRET='local-dev-refresh-token-pepper'
export JWT_KEY_ID='local-dev'
export JWT_PRIVATE_KEY_PEM="$(cat "$KEY_DIR/jwt_private_key.pem")"
export JWT_PUBLIC_KEY_PEM="$(cat "$KEY_DIR/jwt_public_key.pem")"
# 初始化/重建 DB会清库重建适合开发环境
BACKUP=0 ./scripts/db/rebuild_iam_db.sh
cargo run
```
启动后:
- IAM Scalar`http://127.0.0.1:3000/scalar`
- JWKS`http://127.0.0.1:3000/.well-known/jwks.json`
## 4. 启动 cms-service本地验签 + 调 IAM 裁权)
在另一个终端中执行(建议在 `cms-service` 目录下):
```bash
cd /home/shay/project/backend/cms-service
export PORT=3100
export DATABASE_URL='postgres://cms_service_user:cms_service_password@127.0.0.1:5432/cms_service_db'
export IAM_BASE_URL='http://127.0.0.1:3000'
# CMS 默认会走 IAM_BASE_URL + /.well-known/jwks.json 拉取公钥
# 如需显式指定:
# export IAM_JWKS_URL='http://127.0.0.1:3000/.well-known/jwks.json'
# 初始化/重建 DB会回滚并重建 cms schema适合开发环境
./scripts/db/rebuild_cms_db.sh
cargo run
```
启动后:
- CMS Scalar`http://127.0.0.1:3100/scalar`
## 5. 在 Scalar 中跑通“租户 → 注册 → 登录 → 调用 CMS 接口”
### 5.1 在 IAM Scalar 创建租户
打开 `http://127.0.0.1:3000/scalar`
1) 调用 `POST /tenants/register`
示例 body
```json
{ "name": "Tenant A" }
```
从响应中拿到 `tenant_id`UUID
### 5.2 在 IAM Scalar 注册首个用户(自动 Admin + CMS 权限)
调用 `POST /auth/register`
- Header`X-Tenant-ID: <tenant_id>`
- Body
```json
{ "email": "admin@example.com", "password": "Passw0rd!" }
```
重要说明:
- 该租户的**首个用户**会自动触发 bootstrap创建/获取 `Admin` 角色,并授予该租户下的全量非 `iam:*` 权限(包含 `cms:*` 权限),再绑定给该用户。
### 5.3 在 IAM Scalar 登录拿 token
调用 `POST /auth/login`
- Header`X-Tenant-ID: <tenant_id>`
- Body
```json
{ "email": "admin@example.com", "password": "Passw0rd!" }
```
保存响应中的:
- `access_token`
- `refresh_token`(可选,用于测试刷新)
### 5.4 在 CMS Scalar 调用资源接口(验证由 IAM 裁权)
打开 `http://127.0.0.1:3100/scalar`,选择任意需要权限的接口,例如:
- `POST /v1/columns`(需要 `cms:column:write`
在请求中设置:
- `Authorization: Bearer <access_token>`
- `X-Tenant-ID: <tenant_id>`
若一切正常:
- CMS 会先本地验签 tokenauth-kit
- 然后调用 IAM 的 `POST /authorize/check` 判断权限
- IAM 返回 allowed 后CMS 才会执行业务写入
验证建议:
- 观察 iam-service 控制台日志:应能看到 `/authorize/check` 的请求
- 如将 `access_token` 改成无效字符串CMS 会直接返回 401本地验签失败不会去请求 IAM
## 6. 常见问题(本地联调)
### 6.1 CMS 返回 401 MissingAuthHeader
- 检查是否在 CMS 请求里设置了 `Authorization: Bearer <access_token>`
- 检查 token 是否复制完整(不要带引号/空格)
### 6.2 CMS 返回 400 Missing X-Tenant-ID header
- CMS 需要 `X-Tenant-ID`
- 若同时提供 token + header但 tenant_id 不一致会返回 403tenant:mismatch
### 6.3 CMS 返回 403 PermissionDenied
- 表示 IAM 裁权拒绝(例如用户没有 `cms:*` 权限)
- 你可以在 IAM 中调用 `GET /me/permissions` 查看当前用户权限