feat(project): init

This commit is contained in:
2026-02-02 14:30:53 +08:00
commit ccead7e9f6
10 changed files with 718 additions and 0 deletions

124
README.md Normal file
View File

@@ -0,0 +1,124 @@
# auth-kit
`auth-kit` 是一个可复用的认证/多租户中间件库Rust + Axum用于在多个微服务中统一实现
- JWT 认证:从 `Authorization: Bearer <token>` 解析并验证 token注入 `AuthContext`
- 租户隔离:从 `X-Tenant-ID` 解析租户并注入 `TenantId`,并在同时存在 token 与 header 时强制一致性
该 crate 不包含任何业务逻辑、数据库访问或 RBAC 聚合,仅提供“请求上下文注入 + 类型提取器 + JWT 验证能力”。
## 依赖与约定
- Web 框架Axum
- 统一错误类型:`common_telemetry::AppError`
- 头部约定:
- `Authorization: Bearer <access_token>`
- `X-Tenant-ID: <tenant_uuid>`
## 快速开始(在 Axum 中挂载)
推荐链路顺序:
1. `authenticate_with_config`(注入 `AuthContext`
2. `resolve_tenant_with_config`(注入 `TenantId`,并校验 header tenant 与 token tenant 一致)
示例:
```rust
use axum::{Router, middleware::from_fn_with_state};
use auth_kit::middleware::{
auth::{self, AuthMiddlewareConfig},
tenant::{self, TenantMiddlewareConfig},
};
let auth_cfg = AuthMiddlewareConfig {
skip_exact_paths: vec!["/healthz".to_string()],
skip_path_prefixes: vec!["/scalar".to_string()],
jwt: auth_kit::jwt::JwtVerifyConfig::rs256_from_jwks(
"iam-service",
"http://127.0.0.1:3000/.well-known/jwks.json",
)?,
};
let tenant_cfg = TenantMiddlewareConfig {
skip_exact_paths: vec!["/healthz".to_string()],
skip_path_prefixes: vec!["/scalar".to_string()],
};
let app = Router::new()
.layer(from_fn_with_state(tenant_cfg, tenant::resolve_tenant_with_config))
.layer(from_fn_with_state(auth_cfg, auth::authenticate_with_config));
```
## Handler 中如何使用(类型注入)
### AuthContext
`AuthContext` 会从 request extensions 中提取,如果中间件未运行或缺失认证信息,会返回 `AppError::MissingAuthHeader`
```rust
use auth_kit::middleware::auth::AuthContext;
pub async fn handler(AuthContext { user_id, tenant_id, .. }: AuthContext) {
// ...
}
```
### TenantId
`TenantId` 可从 request extensions 中提取;若不存在,会尝试从 `X-Tenant-ID` 解析;缺失则返回 `AppError::BadRequest("Missing X-Tenant-ID header")`
```rust
use auth_kit::middleware::tenant::TenantId;
pub async fn handler(TenantId(tenant_id): TenantId) {
// ...
}
```
## JWT 验证配置JwtVerifyConfig
`JwtVerifyConfig` 定义在 [jwt.rs](file:///home/shay/project/backend/auth-kit/src/jwt.rs)。
- **静态公钥**`rs256_from_pem(issuer, public_key_pem)`
- **JWKS 拉取**`rs256_from_jwks(issuer, jwks_url)`(带缓存与降级)
- **对称密钥(调试/兼容)**`hs256_from_secret(issuer, secret)`
注意点:
- RS256 模式要求 token header 中包含 `kid`(用于从 JWKS 中选 key
- issuer 必须与 token 中 `iss` 一致
- JWKS 目前只支持 RSA + `use=sig` + `alg=RS256`
### JWKS 缓存策略(当前实现)
- HTTP 超时1500ms
- 缓存 TTL300s
- stale-if-error3600sJWKS 拉取失败时可在窗口内使用缓存 key 继续验签)
## Skip 规则(免鉴权路径)
`AuthMiddlewareConfig` / `TenantMiddlewareConfig` 都支持:
- `skip_exact_paths`:精确路径匹配
- `skip_path_prefixes`:前缀匹配
用于跳过如 `/healthz``/scalar``/.well-known/jwks.json` 等公开端点。
## 端到端验证(推荐)
本库自带一个集成测试,用于验证 RS256 + JWKS 的验签路径:
- 测试文件: [jwks_verify.rs](file:///home/shay/project/backend/auth-kit/tests/jwks_verify.rs)
- 运行:
```bash
cd /home/shay/project/backend/auth-kit
cargo test
```
## 已知限制
- 暂未提供“从环境变量自动组装配置”的辅助函数(建议业务服务自行装配 `AuthMiddlewareConfig`
- 暂未实现 ECDSAES256/EdDSAEd25519JWKS 解析