在最初写入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到浏览器,并返回它,然后检查它,但这似乎是由会话中间件处理的。
1条答案
按热度按时间2uluyalo1#
我所需要做的就是用
{withCredentials: true}
从前端发送一个请求然后,我可以在浏览器中设置会话ID,并将其发送到后端,以便中间件处理会话。