sa_token_plugin_actix_web/
extractor.rs

1// Author: 金书记
2//
3//! Actix-web提取器
4
5use actix_web::{FromRequest, HttpRequest, HttpMessage, dev::Payload, error::ErrorUnauthorized};
6use std::future::{ready, Ready};
7use sa_token_core::token::TokenValue;
8
9/// Token 提取器 - 必须存在,否则返回错误
10pub struct SaTokenExtractor(pub TokenValue);
11
12impl FromRequest for SaTokenExtractor {
13    type Error = actix_web::Error;
14    type Future = Ready<Result<Self, Self::Error>>;
15    
16    fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
17        match req.extensions().get::<TokenValue>() {
18            Some(token) => ready(Ok(SaTokenExtractor(token.clone()))),
19            None => ready(Err(ErrorUnauthorized(serde_json::json!({
20                "code": 401,
21                "message": "未登录或 token 无效"
22            })))),
23        }
24    }
25}
26
27/// 可选 Token 提取器 - 不存在也不报错
28pub struct OptionalSaTokenExtractor(pub Option<TokenValue>);
29
30impl FromRequest for OptionalSaTokenExtractor {
31    type Error = actix_web::Error;
32    type Future = Ready<Result<Self, Self::Error>>;
33    
34    fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
35        let token = req.extensions().get::<TokenValue>().cloned();
36        ready(Ok(OptionalSaTokenExtractor(token)))
37    }
38}
39
40/// LoginId 提取器 - 直接获取登录用户的 ID
41pub struct LoginIdExtractor(pub String);
42
43impl FromRequest for LoginIdExtractor {
44    type Error = actix_web::Error;
45    type Future = Ready<Result<Self, Self::Error>>;
46    
47    fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
48        match req.extensions().get::<String>() {
49            Some(login_id) => ready(Ok(LoginIdExtractor(login_id.clone()))),
50            None => ready(Err(ErrorUnauthorized(serde_json::json!({
51                "code": 401,
52                "message": "未登录或 token 无效"
53            })))),
54        }
55    }
56}