如果只讲一个 Rocket 最有辨识度的概念,那一定是:
request guards。
官方文档对它的定义很清楚:
request guard 是一种任意验证策略。
翻成控制塔语言就是:
每个 request guard 都是一位发射前检查员。
它会在发射开始前检查:
- 这次任务有没有权限
- 请求头里有没有令牌
- 当前用户是不是合法操作员
- 是否带了某种上下文
- 当前请求是否符合某项发射规则
一个自定义 request guard 大致长这样:
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:
#[get("/launches")]
fn launches(_key: ApiKey) -> &'static str {
"authorized launches"
}这段代码的真正含义不是“多传了个参数”。
它的语义是:
没有通过这位检查员,就不准进入发射控制台。
#一个关键规则
Rocket 的 request guard 是按参数顺序执行的,并且失败会短路。
也就是说:
#[get("/secure/<id>")]
async fn secure(id: u64, user: UserGuard, admin: AdminGuard) -> String心智上是:
- 先确认路径参数
id - 再检查
user - 再检查
admin - 前面某一项不通过,后面就不继续
这套系统非常像:
先验任务编号
再验值班证
再验高级权限
全部通过,才进入点火流程