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

6.0 KiB
Raw Blame History

本地端到端联调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

docker run --rm -d --name local-pg \
  -e POSTGRES_PASSWORD=postgres \
  -p 5432:5432 \
  postgres:16

创建 iam/cms 两个数据库与用户(示例账号,可按需调整):

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

准备连接串(后续会分别用于两服务):

  • IAMpostgres://iam_service_user:iam_service_password@127.0.0.1:5432/iam_service_db
  • CMSpostgres://cms_service_user:cms_service_password@127.0.0.1:5432/cms_service_db

2. 生成临时 RSA 公私钥RS256

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 PEMBEGIN PRIVATE KEY
  • 公钥PKCS#8 公钥 PEMBEGIN PUBLIC KEY
  • 该目录是临时目录,重启/清理后会消失;适合本地联调

3. 启动 iam-service签发 token + JWKS + 权限裁决)

在一个终端中执行(建议在 iam-service 目录下):

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 Scalarhttp://127.0.0.1:3000/scalar
  • JWKShttp://127.0.0.1:3000/.well-known/jwks.json

4. 启动 cms-service本地验签 + 调 IAM 裁权)

在另一个终端中执行(建议在 cms-service 目录下):

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 Scalarhttp://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

{ "name": "Tenant A" }

从响应中拿到 tenant_idUUID

5.2 在 IAM Scalar 注册首个用户(自动 Admin + CMS 权限)

调用 POST /auth/register

  • HeaderX-Tenant-ID: <tenant_id>
  • Body
{ "email": "admin@example.com", "password": "Passw0rd!" }

重要说明:

  • 该租户的首个用户会自动触发 bootstrap创建/获取 Admin 角色,并授予该租户下的全量非 iam:* 权限(包含 cms:* 权限),再绑定给该用户。

5.3 在 IAM Scalar 登录拿 token

调用 POST /auth/login

  • HeaderX-Tenant-ID: <tenant_id>
  • Body
{ "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 查看当前用户权限