Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SessionMiddleware and RedisSessionStore #859

Open
alucryd opened this issue Dec 6, 2021 · 3 comments
Open

SessionMiddleware and RedisSessionStore #859

alucryd opened this issue Dec 6, 2021 · 3 comments

Comments

@alucryd
Copy link

alucryd commented Dec 6, 2021

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?

@mdtusz
Copy link

mdtusz commented Jan 21, 2022

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.

@maxcountryman
Copy link

maxcountryman commented Feb 21, 2022

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"),
 );

@nyxtom
Copy link
Contributor

nyxtom commented Jul 15, 2022

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(())
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants