I am trying to set up a server backend as an exercise.
I want to store some data in warp_sessions::MemoryStore
but I cannot achieve it. I base on the warp_sessions/examples/shared_mutable_session
example.
I can get the data written into the session. I can read it back immediately after I write into it (variables _a
and _b
in the code below), but they don't persist between the calls. The variables _a_pre
and _b_pre
return empty string on the consecutive handler calls.
Now the questions:
What am I doing wrong?
if I want to use the same session for different routes and I pass the session_store.clone()
in the filter, like it is done in warp example - will the modifications of the session be stored? For now I don't use the cloned instance of the store but the data is lost anyway. I do however need the data to be used by different routes
In the docs of warp_sessions it is said that MemoryStore should not be used in production. What should be used in production instead?
My route handler function looks like this:
pub async fn verify_handler(body: warp::hyper::body::Bytes, mut session_with_store:SessionWithStore<MemoryStore> ) -> Result<(Html<String>, SessionWithStore<MemoryStore>), Rejection> {
session_with_store.cookie_options = warp_sessions::CookieOptions {
cookie_name: "siwe_minimal",
cookie_value: None,
max_age:Some(3600),
domain: None,
path: None,
secure: true,
http_only: true,
same_site: Some(SameSiteCookieOption::Strict),
};
let shared_session = Arc::new(RwLock::new(session_with_store.session));
let _a_pre: String = shared_session
.read()
.unwrap()
.get("nonce")
..unwrap_or_default();
shared_session
.write()
.unwrap()
.insert("nonce", nonce )
.unwrap();
let _a: String = shared_session
.read()
.unwrap()
.get("nonce")
.unwrap();
let msgstr = message.to_string();
let _b_pre: String = shared_session
.read()
.unwrap()
.get("siwe")
.unwrap_or_default();
shared_session
.write()
.unwrap()
.insert("siwe", msgstr)
.unwrap();
let _b: String = shared_session
.read()
.unwrap()
.get("siwe")
.unwrap();
session_with_store.session = Arc::try_unwrap(shared_session)
.unwrap()
.into_inner()
.unwrap();
Ok::<_, Rejection>(
(
warp::reply::html("req".to_string()),
session_with_store
)
)
}
the route is defined like this (if it matters):
let session_store = MemoryStore::new();
let verify_route
= warp::path("verify")
.and(warp::post())
.and(warp::body::bytes())
.and(warp_sessions::request::with_session(session_store, None))
.and_then( verify_handler)
.untuple_one()
.and_then(warp_sessions::reply::with_session)
.recover(handle_rejection)
.with(&cors);
It looks like you're setting the CookieOptions in the route definition to None, meaning that the warp_sessions code will expect a cookie named sid
to get the session ID. Link to code showing this behavior:
However, in the route handler, you override the cookie_options to a different value, with a cookie name of siwe_minimal
. This means that, during the reply portion of the warp_sessions logic, the cookie containing the session ID that will persist your session across calls will be named something different than what the route definition expects.
Link to where Set-Cookie header is defined in the warp_sessions reply code: https://github.com/ajpauwels/warp-sessions/blob/c440817f41c331cfa21a0c3a995be20ab420bb5e/src/session.rs#L98
Link to to_string
definition of CookieOptions which shows how cookie_name
is used: https://github.com/ajpauwels/warp-sessions/blob/c440817f41c331cfa21a0c3a995be20ab420bb5e/src/cookie.rs#L24
In order to solve this, I would suggest either:
Instead of setting CookieOptions to None
in your route definition, set your options there
Keeping None
in the route definition, and removing the options override in the route handler entirely