Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

鉴权

请求头格式

X-CR4-Authorization: Bearer <cloudreve_access_token>

优先用专属头 X-CR4-Authorization——避免与反向代理 / WAF 等基础设施冲突,也便于区分 “给 cr4sync 的 token” 与 “给 cloudreve 的 token”。

缺失时回退标准 Authorization:cr4sync 作为 cloudreve 扩展同源部署时,前端复用 cloudreve 登录态直接带标准 Authorization 更自然;标准客户端(curl 等)也可用标准头访问。两者都在时以 X-CR4-Authorization 为准。

取 token 顺序: X-CR4-Authorization → (缺失) Authorization → (都缺) 401

X-CR4-Authorization 存在但格式非法(非 Bearer <token>),直接判 401,静默回退到 Authorization——专属头一旦显式出现就以它为准。

鉴权流程

                ┌─────────────────────────────────────────┐
                │ middleware/auth.rs                      │
                │ 1. 取 X-CR4-Authorization (缺回退 Authorization) │
                │ 2. 解析 Bearer 前缀                     │
                │ 3. base64 解 JWT payload (不验签)       │
                │    - 取 sub (user_id)                   │
                │    - 校验 exp 未过期                    │
                │ 4. AuthValidator.validate(token)        │
                │    - moka cache.get(token)              │
                │    - hit → 返 AuthResult                │
                │    - miss → GET cr4/user/info/{sub}     │
                │              header: Authorization=...  │
                │              → 200 + body.code=0 →      │
                │                is_admin =               │
                │                  admin_groups contains  │
                │                  data.group.name        │
                │                db.upsert_user(...)      │
                │                cache TTL = min(60s,     │
                │                  exp - now - 30s)       │
                │ 5. 注入 AuthContext 到 extension        │
                └─────────────────────────────────────────┘

AuthContext

注入到 axum request extension,handler 用 Extension<AuthContext> 取:

#![allow(unused)]
fn main() {
pub struct AuthContext {
    pub user_id: String,           // Cloudreve sub
    pub is_admin: bool,            // group.name 命中 admin 组名集合
    pub token: String,             // 原始 access_token (现场上传 Cloudreve 时用)
    pub group_name: String,        // 用户组名
    pub email: Option<String>,
    pub nickname: Option<String>,
}
}

缓存

AuthValidator 内置 moka::future::Cache<String, AuthResult>

维度
key原始 access_token
TTLmin(60s, jwt.exp - now - 30s)
容量默认 10000 entry

也即:token revoke 后 cr4sync 端最多 60s 后感知,admin 角色变更同理。

admin 自动识别

cr4sync 不维护自己的 admin 列表。每次 /user/info 响应都看 data.group.name,并与 admin 组名集合比对:

{
  "code": 0,
  "data": {
    "id": "sub-xxx",
    "email": "a@example.com",
    "nickname": "Alice",
    "group": {
      "name": "管理员"
    }
  }
}

默认 admin 组名集合包含 "Admin""管理员",任一命中即 is_admin = true。如果 [serve.cr4].admin_group 配了值,则只认该配置值。

require_admin middleware

/admin/* 子树路由额外挂 require_admin middleware:从 extension 取 AuthContextis_admin == falseApiError::Forbidden(HTTP 403 + envelope.code=1000)。

白名单

  • /api/v4/cr4sync/health 不需要鉴权。
  • embed-web 构建下 /extensions/cr4sync(内嵌前端 SPA 静态资产)不走鉴权——前端加载后再用 token 调 API。详见 部署

鉴权失败回执

现象HTTPenvelope
头缺失 (X-CR4-Authorization / Authorization 都无) / 非 Bearer401{ code: 1000, msg: "...", data: null, request_id }
JWT base64 解失败401{ code: 1000, msg: "invalid token format", ... }
JWT exp 已过401{ code: 1000, msg: "token expired", ... }
Cloudreve /user/info 返非 0 code401{ code: <cloudreve.code>, msg: <cloudreve.msg>, ... } 透传
Cloudreve /user/info 网络失败500{ code: 3000, msg: "upstream unavailable", ... }
非 admin 访问 /admin/*403{ code: 1000, msg: "admin required", ... }

与 Cloudreve token 流转

仅鉴权时使用调用方的 access_token 校验身份;后续上传 Cloudreve 也强制使用调用方 token,绝不读站长 token.json。详见 Migrate 接口 的“长任务 token 续期“段。