#flash #tide #log #api #request-response

tide-flash

Tide (http-rs/tide) 闪光消息中间件

2个版本

0.1.1-beta.12022年7月11日
0.1.0 2022年7月11日

#1122 in HTTP服务器

MIT 许可证

12KB
178 代码行

tide-flash

Latest version Documentation License

http-rs/tide flash消息中间件,支持通过Cookies配置闪光存储。可扩展以支持其他存储机制,如会话。主要是一种向客户端发送一次性日志消息的机制,这些消息可能不会在重定向(如请求登录)时保持状态。这通常用于认证请求,其中登录在HTTP POST上,并且响应需要同时:返回重定向以及一次性日志消息以渲染。

示例

要设置配置CookieStore的闪光中间件,请使用以下默认设置

use tide::log::LogMiddleware;
use tide_flash::{cookies::CookieStore, FlashMiddleware};

mod routes;

#[async_std::main]
async fn main() -> tide::Result<()> {
    let mut app = tide::new();
    dotenv::dotenv().ok();
    env_logger::init();

    app.with(LogMiddleware::new());
    app.with(FlashMiddleware::new(CookieStore::default()));

    routes::configure(&mut app);

    let host = std::env::var("HOST").unwrap_or(String::from("0.0.0.0"));
    let port: u16 = std::env::var("PORT")?.parse()?;
    app.listen((host, port)).await?;

    Ok(())
}

CookieStore的默认设置是

impl Default for CookieConfig {
    fn default() -> Self {
        Self {
            max_age: time::Duration::seconds(60),
            site: SameSite::Lax,
            http_only: true,
            path: String::from("/"),
        }
    }
}

现在要简单地使用它,您可以通过以下方式导入响应扩展

use tide_flash::ext::*;
use tide::{Response, Request, Redirect};

pub async fn authenticate(mut req: Request<State>) -> tide::Result {
    match req.body_form::<UserForm>().await {
        Ok(form) => {
            if form.username == "foo" && form.password == "bar" {
                let claims = Claims {
                    username: String::from("foo"),
                    exp: 10000000000,
                    sub: String::from("asdf"),
                    uid: 1,
                };
                req.login(claims)?;
                Ok(Redirect::new("/").into())
            } else {
                let mut res: Response = Redirect::new("/").into();
                res.flash_error("invalid credentials");
                Ok(res)
            }
        }
        Err(e) => {
            let mut res: Response = Redirect::new("/").into();
            res.flash_error(e.to_string());
            Ok(res)
        }
    }
}

这里有多种简单的响应扩展实用工具可以使用,包括

pub trait ResponseFlashExt {
    fn flash(&mut self, level: &str, msg: String);
    fn flash_success<S: Into<String>>(&mut self, msg: S);
    fn flash_info<S: Into<String>>(&mut self, msg: S);
    fn flash_warn<S: Into<String>>(&mut self, msg: S);
    fn flash_error<S: Into<String>>(&mut self, msg: S);
    fn flash_debug<S: Into<String>>(&mut self, msg: S);
}

要从tide::Request获取相应的闪光消息,请使用请求扩展上的flash函数

impl<'request, T: Serialize> Context<'request, T> {
    pub fn with_data(request: &'request Request<State>, data: T) -> Self {
        Self {
            request,
            flash: request.flash(),
            claims: request.claims(),
            data: Some(data),
        }
    }

    pub fn render(self, template: &str) -> Result<String, handlebars::RenderError> {
        self.request.state().render(
            template,
            &serde_json::json!({
                "flash": self.flash,
                "claims": self.claims,
                "data": self.data
            }),
        )
    }
}

依赖关系

~12–22MB
~345K SLoC