Open alucryd opened 2 years ago
I don't have a shareable working example at the moment without some cleanup work, but you can use redis sessions with something like this:
use async_redis_session::RedisSessionStore;
use tide::sessions::SessionMiddleware;
#[async_std::main]
async fn main() -> tide::Result<()> {
let server = tide::new();
let redis_client = redis::Client::open("rediss://some_address@user:pass:port/").unwrap();
let store = RedisSessionStore::from_client(redis_client).with_prefix("user-session:");
let sessions_mw = SessionMiddleware::new(store, "c0oK1eSeCr3t".as_bytes())
.with_cookie_name("sid")
.with_cookie_path("/")
.without_save_unchanged();
server.with(sessions_mw);
// Rest of your app setup.
Ok(())
}
Then in request handlers, you can access the session as described in the docs.
You will likely need to pin async-redis-session = "0.1.1"
since Tide still has not been updated to support versions beyond that.
Once you do, all you need to do from there is something like:
let mut app = tide::new();
let session_store = RedisSessionStore::new("redis://localhost:6379").expect("Could not connect to Redis");
app.with(
SessionMiddleware::new(session_store, b"change me to some super secret bytes"),
);
I've implemented something similar in my full stack app sample using the async-redis-session = "0.2.2"
https://github.com/nyxtom/rust-twitter-clone/blob/master/src/main.rs#L41-L44 The versions just need to line up in order for it to work. At the moment I'm using 0.17.0-beta.1.
[package]
name = "web"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
async-std = { version = "1.12.0", features = ["attributes"] }
handlebars = "4.3.1"
serde = { version = "1.0.138", features = ["derive"] }
tide = { version = "0.17.0-beta.1", features = ["sessions", "h1-server", "cookies"] }
tide-flash = { version = "0.1.1-beta.1" }
env_logger = "0.9.0"
dotenv = "0.15.0"
time = { version = "0.2.6", default-features = false, features = ["std"] }
serde_json = "1.0.82"
async-redis-session = "0.2.2"
libreauth = { version = "0.15.0", features = ["oath-uri"] }
qrcode = "0.12.0"
async-trait = "0.1.56"
validator = { version = "0.15.0", features = ["derive"] }
use async_redis_session::RedisSessionStore;
use registry::State;
use serde::{Deserialize, Serialize};
use tide::log::LogMiddleware;
use tide_flash::{cookies::CookieStore, FlashMiddleware};
mod registry;
mod request_ext;
mod route_ext;
mod routes;
mod templates;
mod prelude {
pub use crate::request_ext::*;
pub use crate::route_ext::*;
pub use tide_flash::ext::*;
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
sub: String,
username: String,
uid: u64,
exp: usize,
totp_enabled: bool,
totp_attempt: usize,
totp: Option<usize>,
}
#[async_std::main]
async fn main() -> tide::Result<()> {
let mut app = tide::with_state(State::new());
dotenv::dotenv().ok();
env_logger::init();
app.with(LogMiddleware::new());
// configure openid connect and session middleware
let session_secret = std::env::var("SESSION_SECRET")?;
let redis_url = std::env::var("REDIS_URL")?;
app.with(tide::sessions::SessionMiddleware::new(
RedisSessionStore::new(redis_url)?,
session_secret.as_bytes(),
));
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(())
}
Tide does not recommend the use of MemoryStore in production, but using RedisSessionStore from async-redis-session doesn't seem to be straightforward. Do you guys have a working example?