如何使用actix_session和RedisActorSessionStore跨路由持久化数据

x4shl7ld  于 2023-10-15  发布在  Redis
关注(0)|答案(1)|浏览(131)

在最初写入Redis数据库后,我很难检索路由上的会话数据。
当我插入到会话中时,我可以使用session.entries()或session.get::<>()查看这些语句。当我从另一个路由尝试此操作时,会话总是空的。
我假设这意味着会话不会在路由之间持续。我不完全理解会话是如何在浏览器上排序的,除了它是安全存储的,并自动与HTTP请求一起发送?这使得很难判断问题是如何将会话数据发送到浏览器,还是如何从浏览器检索会话。
下面是我的一些代码片段。

登录页面

#[post("/login")]
async fn login(session: Session, user_info: web::Json<LoginDetails>) -> impl Responder {

...
password auth
...
session.insert("user_id".to_string(), user_id);
                session.insert("status_level".to_string(), status_level);
                session.insert("login_status".to_string(), true);

                let user_session = UserSession {
                    session_string: session_string.to_string(),
                    session_details
                };

                dbg!(session.entries()); // This shows the entries :)
                dbg!(session.get::<u8>("user_id"));

                return HttpResponse::Ok().status(StatusCode::from_u16(200).unwrap()).json(user_session);
            },
...

会话检查中间件

pub fn validate_session(session: &Session) -> Result<u8, HttpResponse> {
    let user_id: Option<u8> = session.get("user_id").unwrap_or_else(|err| { println!("Error getting user_id from session: {}", err); None });

    dbg!(session.entries()); //This will be empty :(

    dbg!(&user_id);
    match user_id {
        Some(id) => {
            // keep the user's session alive
            session.renew();
            Ok(id)
        }
        None => Err(HttpResponse::Unauthorized().json("Unauthorized")),
    }
}

会话保护页面

#[get("/campaign_names")]
async fn campaign_names(session: Session, req: HttpRequest) -> impl Responder {

    let id = validate_session(&session).unwrap_or(0);

    println!("id {}",id); // prints 0
...

我的主路由

#[actix_web::main]
async fn main() -> std::io::Result<()> {

    let secret_key = Key::generate();

    HttpServer::new(move || {
        let cors = Cors::permissive();
        App::new()
            .wrap(cors)
            .wrap(
                SessionMiddleware::builder(
                    RedisActorSessionStore::new("127.0.0.1:6379"),
                    secret_key.clone(),
                )
                    // allow the cookie to be accessed from javascript
                    .cookie_http_only(false)
                    // allow the cookie only from the current domain
                    .cookie_same_site(SameSite::Strict)
                    .build(),
            )
            .service(campaign_names)

我肯定漏掉了什么明显的东西?
下面是我模仿的例子:https://github.com/actix/actix-extras/blob/master/actix-session/examples/authentication.rs
我试过使用非演员会话。我还在Redis中验证了数据正在设置。
感觉就像我应该发送一个会话ID到浏览器,并返回它,然后检查它,但这似乎是由会话中间件处理的。

2uluyalo

2uluyalo1#

我所需要做的就是用{withCredentials: true}从前端发送一个请求
然后,我可以在浏览器中设置会话ID,并将其发送到后端,以便中间件处理会话。

相关问题