Add middleware to require authentication for some routes
All checks were successful
Push Workflows / rustfmt (push) Successful in 14s
Push Workflows / tailwind-build (push) Successful in 13s
Push Workflows / clippy (push) Successful in 25s
Push Workflows / test (push) Successful in 34s
Push Workflows / docs (push) Successful in 31s
Push Workflows / build (push) Successful in 59s
Push Workflows / nix-build (push) Successful in 5m27s

This commit is contained in:
2026-06-28 11:56:18 -04:00
parent 62a7103423
commit 0463714882
3 changed files with 68 additions and 2 deletions

View File

@@ -1,7 +1,13 @@
use dioxus::{fullstack::axum::Router, server::axum::Extension}; use dioxus::{
fullstack::axum::{Router, middleware::from_fn},
server::axum::Extension,
};
use crate::App; use crate::App;
use crate::server::{auth::build_auth_layer, config, database, key_val_store}; use crate::server::{
auth::build_auth_layer, config, database, key_val_store,
require_auth_mw::require_auth_middleware,
};
use crate::util::error::{Contextualize, Error, Result}; use crate::util::error::{Contextualize, Error, Result};
pub fn main() -> Result<std::convert::Infallible> { pub fn main() -> Result<std::convert::Infallible> {
@@ -31,6 +37,7 @@ async fn router_setup() -> Result<Router> {
let auth_layer = build_auth_layer(db_pool.clone(), key_val_pool); let auth_layer = build_auth_layer(db_pool.clone(), key_val_pool);
let router = dioxus::server::router(App) let router = dioxus::server::router(App)
.layer(from_fn(require_auth_middleware))
.layer(Extension(config)) .layer(Extension(config))
.layer(Extension(db_pool)) .layer(Extension(db_pool))
.layer(auth_layer); .layer(auth_layer);

View File

@@ -3,5 +3,6 @@ pub mod config;
pub mod database; pub mod database;
pub mod key_val_store; pub mod key_val_store;
pub mod main; pub mod main;
pub mod require_auth_mw;
pub use main::main; pub use main::main;

View File

@@ -0,0 +1,58 @@
use dioxus::fullstack::{
axum::{body::Body, extract::Request, middleware::Next},
extract::FromRequestParts,
http::Response,
};
use dioxus::prelude::*;
use crate::server::auth::AuthSession;
const ALLOWED_PATH_PREFIX: [&str; 1] = ["/assets/"];
const ALLOWED_PATHS: [&str; 5] = [
"/login",
"/signup",
"/api/v1/auth/login",
"/api/v1/auth/signup",
"/favicon.ico",
];
/// Axum middleware to redirect an unauthenticated request to /login unless it matches one of the allowed paths
pub async fn require_auth_middleware(
req: Request,
next: Next,
) -> Result<Response<Body>, (StatusCode, &'static str)> {
let path = req.uri().path();
if ALLOWED_PATH_PREFIX
.iter()
.any(|prefix| path.starts_with(prefix))
|| ALLOWED_PATHS.contains(&path)
{
let response = next.run(req).await;
return Ok(response);
}
let (mut parts, body) = req.into_parts();
let auth_session = AuthSession::from_request_parts(&mut parts, &()).await?;
if auth_session.user.is_none() {
let response = Response::builder()
.status(StatusCode::TEMPORARY_REDIRECT)
.header("Location", "/login")
.body(Body::empty())
.map_err(|_| {
(
StatusCode::INTERNAL_SERVER_ERROR,
"Failed to build response",
)
})?;
return Ok(response);
}
let req = Request::from_parts(parts, body);
let response = next.run(req).await;
Ok(response)
}