全书目录

第四十四篇:Rocket 完全指南 —— 火箭发射控制塔宇宙

第七章:Request Guards —— 控制塔最核心的“发射前检查员”

1 分钟 414 字 第 816 / 962 个阅读单元

如果只讲一个 Rocket 最有辨识度的概念,那一定是:

request guards。

官方文档对它的定义很清楚:

request guard 是一种任意验证策略。

翻成控制塔语言就是:

每个 request guard 都是一位发射前检查员。

它会在发射开始前检查:

  • 这次任务有没有权限
  • 请求头里有没有令牌
  • 当前用户是不是合法操作员
  • 是否带了某种上下文
  • 当前请求是否符合某项发射规则

一个自定义 request guard 大致长这样:

rust
use rocket::http::Status;
use rocket::request::{self, FromRequest, Outcome, Request};

struct ApiKey;

#[rocket::async_trait]
impl<'r> FromRequest<'r> for ApiKey {
    type Error = ();

    async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
        match req.headers().get_one("x-api-key") {
            Some("launch-secret") => Outcome::Success(ApiKey),
            _ => Outcome::Error((Status::Unauthorized, ())),
        }
    }
}

然后直接放进 handler:

rust
#[get("/launches")]
fn launches(_key: ApiKey) -> &'static str {
    "authorized launches"
}

这段代码的真正含义不是“多传了个参数”。

它的语义是:

没有通过这位检查员,就不准进入发射控制台。

#一个关键规则

Rocket 的 request guard 是按参数顺序执行的,并且失败会短路。

也就是说:

rust
#[get("/secure/<id>")]
async fn secure(id: u64, user: UserGuard, admin: AdminGuard) -> String

心智上是:

  1. 先确认路径参数 id
  2. 再检查 user
  3. 再检查 admin
  4. 前面某一项不通过,后面就不继续

这套系统非常像:

text
先验任务编号
再验值班证
再验高级权限
全部通过,才进入点火流程