Skip to main content

sa_token_plugin_rocket_v05/
layer.rs

1//! `SaTokenLayer` Fairing: runs shared **`run_auth_flow`**, then sets **`SaTokenContext`** / clears after response.
2//! `SaTokenLayer` Fairing:执行统一的 **`run_auth_flow`**,设置 **`SaTokenContext`**,响应后清理。
3use rocket::{Data, Request, Response};
4use rocket::fairing::{Fairing, Info, Kind};
5use sa_token_core::SaTokenContext;
6use sa_token_plugin_rocket_core::SaTokenState;
7
8use crate::adapter::RocketCapturedRequest;
9
10/// Rocket Fairing using **`RocketCapturedRequest`** + **`run_auth_flow`** (rocket-core pipeline).
11/// 使用 **`RocketCapturedRequest`** + **`run_auth_flow`**(rocket-core 流水线)的 Fairing。
12pub struct SaTokenLayer {
13    state: SaTokenState,
14}
15
16impl SaTokenLayer {
17    pub fn new(state: SaTokenState) -> Self {
18        Self { state }
19    }
20}
21
22#[rocket::async_trait]
23impl Fairing for SaTokenLayer {
24    fn info(&self) -> Info {
25        Info {
26            name: "Sa-Token Authentication",
27            kind: Kind::Request | Kind::Response,
28        }
29    }
30
31    async fn on_request(&self, req: &mut Request<'_>, _: &mut Data<'_>) {
32        let adapter = RocketCapturedRequest::capture(req, self.state.manager.config.token_name.as_str());
33        let flow =
34            sa_token_plugin_rocket_core::run_auth_flow(&adapter, &self.state.manager, None).await;
35
36        if let Some(ref t) = flow.token {
37            req.local_cache(|| Some(t.clone()));
38        }
39        if let Some(ref id) = flow.login_id {
40            req.local_cache(|| Some(id.clone()));
41        }
42
43        // 1) 跨 await 串号时 thread_local 兜底(旧 StpUtil::*_current 同步路径)
44        SaTokenContext::set_current(flow.context.clone());
45        // 2) 推荐:请求级 Arc,供 `SaCtx` guard 读取(见 `extractor::SaCtx`)
46        req.local_cache(|| std::sync::Arc::new(flow.context));
47    }
48
49    async fn on_response<'r>(&self, _req: &'r Request<'_>, _res: &mut Response<'r>) {
50        SaTokenContext::clear();
51    }
52}