2个版本
0.1.1-beta.1 | 2022年7月11日 |
---|---|
0.1.0 | 2022年7月11日 |
#1122 in HTTP服务器
12KB
178 代码行
tide-flash
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