Warp Session中存储的数据不会持久保存 [已解决 – 但不知道原因]

huangapple go评论79阅读模式
英文:

Data stored in warp Session does not persist [SOLVED - but don't know why]

问题

我在我的Rust之旅的开头。尝试设置服务器后端作为一项练习。我卡住了。请帮帮我。

我试图将一些数据存储在warp_sessions::MemoryStore中,但我无法实现它。我以warp_sessions/examples/shared_mutable_session示例为基础。

我可以将数据写入会话中。我可以在写入后立即读取它(在下面的代码中的变量_a_b),但它们在调用之间不会保留。在连续的处理程序调用上,变量_a_pre_b_pre返回空字符串。

现在的问题是:

  • 我做错了什么?[代码如下]

  • 如果我想在不同的路由中使用相同的会话,并且我将session_store.clone()传递给过滤器,就像在warp示例中一样,会话的修改会被保存吗?目前我不使用存储的克隆实例,但数据仍然丢失。然而,我确实需要数据被不同的路由使用。

  • 在warp_sessions的文档中说MemoryStore不应该在生产中使用。在生产中应该使用什么?

我的路由处理函数如下:

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

}

路由定义如下(如果有关系的话):

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

更新:

有趣的是,当我从lambda中调用处理程序时,它可以工作。不过我不知道为什么:

let verify_route 
    = warp::path("verify")
    .and(warp::post())
    .and(warp::body::bytes())
    .and(warp_sessions::request::with_session(session_store, None)) 
    .and_then(move |body: warp::hyper::body::Bytes, mut session_with_store: SessionWithStore<MemoryStore>| async move {  
      let result =  verify_handler(body, session_with_store.clone()).await.unwrap();        
      Ok::<_, Rejection>((
          warp::reply::html("_foo".to_string()),
          session_with_store,
      ))
    },
    )
    .untuple_one()
    .and_then(warp_sessions::reply::with_session)
    .with(&cors); 
英文:

I am at the beginning of my Rust journey. Trying to set up a server backend as an exercise. I am stuck. Please help.

I am trying 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? [code below]

  • 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&lt;MemoryStore&gt; ) -&gt; Result&lt;(Html&lt;String&gt;, SessionWithStore&lt;MemoryStore&gt;), Rejection&gt;  {

  session_with_store.cookie_options = warp_sessions::CookieOptions {
    cookie_name: &quot;siwe_minimal&quot;,
    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(&quot;nonce&quot;)  
      ..unwrap_or_default();

  shared_session
      .write()
      .unwrap()
      .insert(&quot;nonce&quot;, nonce )   
      .unwrap();
    
  let _a: String = shared_session
      .read()
      .unwrap()
      .get(&quot;nonce&quot;)  
      .unwrap();

  let msgstr = message.to_string();

  let _b_pre: String = shared_session
  .read()
  .unwrap()
  .get(&quot;siwe&quot;)  
  ..unwrap_or_default(); 

  shared_session
      .write()
      .unwrap()
      .insert(&quot;siwe&quot;, msgstr)  
      .unwrap();

       
  let _b: String = shared_session
  .read()
  .unwrap()
  .get(&quot;siwe&quot;)  
  .unwrap();

   
  session_with_store.session = Arc::try_unwrap(shared_session)
      .unwrap()
      .into_inner()
      .unwrap(); 


  Ok::&lt;_, Rejection&gt;(
    (
      warp::reply::html(&quot;req&quot;.to_string()),
      session_with_store
    )
  )

}

the route is defined like this (if it matters):

let session_store = MemoryStore::new();
let verify_route 
    = warp::path(&quot;verify&quot;)
    .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(&amp;cors); 

UPDATE:

Interestingly when i call the handler from the lambda, it works. I dont know why though:

let verify_route 
    = warp::path(&quot;verify&quot;)
    .and(warp::post())
    .and(warp::body::bytes())
    .and(warp_sessions::request::with_session(session_store, None)) 
    .and_then( move |body: warp::hyper::body::Bytes, mut session_with_store: SessionWithStore&lt;MemoryStore&gt;| async move {  
      let result =  verify_handler(body, session_with_store.clone()).await.unwrap();        
      Ok::&lt;_, Rejection&gt;((
          warp::reply::html(&quot;_foo&quot;),
          session_with_store,
      ))
    },
    )
    .untuple_one()
    .and_then(warp_sessions::reply::with_session)
    .with(&amp;cors); 

答案1

得分: 1

看起来你在路由定义中将CookieOptions设置为None,这意味着warp_sessions代码将期望一个名为sid的Cookie来获取会话ID。显示此行为的代码链接:

https://github.com/ajpauwels/warp-sessions/blob/c440817f41c331cfa21a0c3a995be20ab420bb5e/src/request.rs#L17

然而,在路由处理程序中,你将cookie_options覆盖为一个不同的值,使用的Cookie名称是siwe_minimal。这意味着在warp_sessions逻辑的回复部分期间,包含会话ID的Cookie将被命名为与路由定义期望的不同的名称。

在warp_sessions回复代码中定义Set-Cookie标头的链接:https://github.com/ajpauwels/warp-sessions/blob/c440817f41c331cfa21a0c3a995be20ab420bb5e/src/session.rs#L98

显示CookieOptions的to_string定义,其中显示了如何使用cookie_name:https://github.com/ajpauwels/warp-sessions/blob/c440817f41c331cfa21a0c3a995be20ab420bb5e/src/cookie.rs#L24

为了解决这个问题,我建议:

  1. 在你的路由定义中,不要将CookieOptions设置为None,而是在那里设置你的选项。

  2. 保留路由定义中的None,并完全删除路由处理程序中的选项覆盖。

英文:

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:

https://github.com/ajpauwels/warp-sessions/blob/c440817f41c331cfa21a0c3a995be20ab420bb5e/src/request.rs#L17

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:

  1. Instead of setting CookieOptions to None in your route definition, set your options there

  2. Keeping None in the route definition, and removing the options override in the route handler entirely

huangapple
  • 本文由 发表于 2023年7月31日 22:04:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76804403.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定