6.0 KiB
6.0 KiB
本地端到端联调(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-service:3000
- cms-service:3100
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
准备连接串(后续会分别用于两服务):
- 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)
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 目录下):
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 目录下):
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:
- 调用
POST /tenants/register
示例 body:
{ "name": "Tenant A" }
从响应中拿到 tenant_id(UUID)。
5.2 在 IAM Scalar 注册首个用户(自动 Admin + CMS 权限)
调用 POST /auth/register:
- Header:
X-Tenant-ID: <tenant_id> - Body:
{ "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:
{ "email": "admin@example.com", "password": "Passw0rd!" }
保存响应中的:
access_tokenrefresh_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 会先本地验签 token(auth-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 不一致会返回 403(tenant:mismatch)
6.3 CMS 返回 403 PermissionDenied
- 表示 IAM 裁权拒绝(例如用户没有
cms:*权限) - 你可以在 IAM 中调用
GET /me/permissions查看当前用户权限