You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm encountering an issue regarding session-cookie authentication in my Axum application. I'm trying to use the tower-sessions middleware to store the session and then utilize the is_logged_in middleware to verify whether the user has included the cookie.
Initially, I planned to use req.extensions() to retrieve the token for verification, which would eliminate the need for the session middleware to extract the session. However, despite sending the cookie with the request, I can't seem to find it. When I try to directly use session: Session in the is_logged_in function, it results in an error.
Could anyone help me with how to resolve this issue?
Thank you!
middleware
use crate::auth::*;
use crate::error::AppError;
// use crate::model::AppState;
use crate::models::user::*;
use axum::extract::{Request, State};
use axum::middleware::Next;
use axum::response::IntoResponse;
use std::sync::Arc;
use tower_cookies::{Cookie, Cookies}; // 使用 `tower_cookies` 来处理 cookies
use tower_sessions::{session, Session};
use tracing::{debug, error, info};
pub async fn is_logged_in(
session: Session,
State(state): State<Arc<AppState>>,
mut req: Request, // 请求包含泛型 B
next: Next, // Next 也包含泛型 B
) -> Result<impl IntoResponse, AppError> {
// 从 Session 中提取 token
let session_token = session.get::<String>("token").await.map_err(|_| {
error!("token not found");
AppError::TokenInvalid
})?;
match session_token {
Some(session_token) => {
// 验证 token 并检查用户是否存在
let username = verify_token(&session_token, &state.key)
.await
.map_err(|e| {
error!("{}", e);
AppError::TokenInvalid
})?;
let account_exists =
sqlx::query_scalar::<_, i64>("SELECT COUNT(1) FROM account WHERE username = ?")
.bind(&username)
.fetch_one(&state.pool)
.await
.map_err(|e| {
error!("{}", e);
AppError::DataBaseError
})?;
if account_exists == 0 {
return Err(AppError::SessionError);
}
// 用户已登录,继续处理请求
Ok(next.run(req).await)
}
_ => {
error!("token not found");
return Err(AppError::SessionError);
}
}
}
run axum server
async fn run(key:&str)->anyhow::Result<()>{
let timeout = Duration::hours(2);
let session_store = MemoryStore::default();
let session_layer = SessionManagerLayer::new(session_store)
//false 表示在开发环境下(通常是 HTTP)也允许使用 cookie
.with_secure(false)
.with_name("token")
// 设置会话过期时间为 2 hours
.with_expiry(Expiry::OnInactivity(timeout));
// 从环境变量中读取 DATABASE_URL
let database_url = env::var("DATABASE_URL")?;
info!("database_url: {}", database_url);
// 创建 MySQL 连接池
let pool = MySqlPoolOptions::new()
.max_connections(5)
.connect(&database_url)
.await?;
let app_state = Arc::new(AppState {
pool,
key: key.to_string(),
// users: DashMap::new(),
// chat_rooms: DashMap::new(),
});
debug!("app_state: {:?}", app_state);
let addr = format!("0.0.0.0:3000");
info!("Server is running on {}",addr);
let listener = tokio::net::TcpListener::bind(addr).await?;
let app = Router::new()
.layer(session_layer.clone())
.route("/room/delete/:chatroom_id", get(delete_chatroom))
.route("/room/create", post(create_chatroom))
.route("/logout", get(logout_handle))
.route("/profile/:user_id", get(get_user_profile))
.layer(TraceLayer::new_for_http()
.make_span_with(|request: &Request<Body>| {
tracing::info_span!("http_request", method = %request.method(), uri = %request.uri())
})
.on_response(DefaultOnResponse::new()))
.with_state(app_state.clone())
.route_layer(axum::middleware::from_fn_with_state(app_state.clone(),is_logged_in));
let login_app:Router = Router::new()
.route("/test", get(test_conn))
.route("/register", post(register_handle))
.route("/login", post(handle_login))
.layer(session_layer)
.layer(TraceLayer::new_for_http()
.make_span_with(|request: &Request<Body>| {
tracing::info_span!("http_request", method = %request.method(), uri = %request.uri())
})
.on_response(DefaultOnResponse::new()))
.with_state(app_state.clone());
// 将两个路由合并
let combined_app = app.merge(login_app);
axum::serve(listener,combined_app).await.unwrap();
Ok(())
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Summary
Hello everyone,
I'm encountering an issue regarding session-cookie authentication in my Axum application. I'm trying to use the tower-sessions middleware to store the session and then utilize the is_logged_in middleware to verify whether the user has included the cookie.
Initially, I planned to use req.extensions() to retrieve the token for verification, which would eliminate the need for the session middleware to extract the session. However, despite sending the cookie with the request, I can't seem to find it. When I try to directly use session: Session in the is_logged_in function, it results in an error.
Could anyone help me with how to resolve this issue?
Thank you!
middleware
run axum server
axum version
0.7.5
Beta Was this translation helpful? Give feedback.
All reactions