From d119f958f60320438ed27bcaed2c255e617c11a0 Mon Sep 17 00:00:00 2001 From: yly Date: Thu, 14 Mar 2024 21:55:12 +0800 Subject: [PATCH] =?UTF-8?q?DONE,=E5=A4=84=E7=90=86=E9=87=8D=E5=AE=9A?= =?UTF-8?q?=E5=90=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- auth.conf | 1 - loginpage.html | 2 +- src/config.rs | 22 +++++++++++----------- src/entities/mod.rs | 4 ++-- src/main.rs | 3 +-- src/services/auth.rs | 14 +++++++++----- src/services/mod.rs | 30 ++++++++++-------------------- 7 files changed, 34 insertions(+), 42 deletions(-) diff --git a/auth.conf b/auth.conf index f6b67c9..3270370 100644 --- a/auth.conf +++ b/auth.conf @@ -11,7 +11,6 @@ server { proxy_set_header X-Original-URI $scheme://$host$request_uri; proxy_pass http://protected/; } - location location = /aaron/auth { internal; proxy_pass http://localhost:3000/auth; diff --git a/loginpage.html b/loginpage.html index 349a995..df23891 100644 --- a/loginpage.html +++ b/loginpage.html @@ -63,7 +63,7 @@

Login

-
+ diff --git a/src/config.rs b/src/config.rs index ea59be9..45d73da 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,26 +1,26 @@ use once_cell::sync::Lazy; use std::env; -pub const COOKIE_NAME: Lazy = +pub static COOKIE_NAME: Lazy = Lazy::new(|| env::var("COOKIE_NAME").unwrap_or("aaron_auth".to_string())); -pub const SESSION_ACTIVE_TIME: Lazy = Lazy::new(|| { +pub static SESSION_ACTIVE_TIME: Lazy = Lazy::new(|| { env::var("SESSION_ACTIVE_TIME") .ok() .and_then(|value| value.parse().ok()) .unwrap_or(600) }); -pub const COOKIE_DOMAIN: Lazy = +pub static COOKIE_DOMAIN: Lazy = Lazy::new(|| env::var("DOMAIN").ok().unwrap_or(".aaronhu.cn".to_owned())); -pub const LOGIN_PAGE_HTML: &str = include_str!("../loginpage.html"); -pub const REGISTER_PAGE_HTML: &str = include_str!("../register.html"); -pub const PORT: Lazy = Lazy::new(|| env::var("PORT").unwrap_or("3000".to_string())); +pub static LOGIN_PAGE_HTML: &str = include_str!("../loginpage.html"); +pub static REGISTER_PAGE_HTML: &str = include_str!("../register.html"); +pub static PORT: Lazy = Lazy::new(|| env::var("PORT").unwrap_or("3000".to_string())); // 部署此应用的URL,默认为/aaron -pub const HOME_URL: Lazy = +pub static HOME_URL: Lazy = Lazy::new(|| env::var("HOME_URL").unwrap_or("/aaron".to_owned())); -pub const DATABASE_URL: Lazy = +pub static DATABASE_URL: Lazy = Lazy::new(|| env::var("DATABASE_URL").unwrap_or("".to_owned())); -pub const RP_ID: Lazy = +pub static RP_ID: Lazy = Lazy::new(|| env::var("RP_ID").unwrap_or("localhost".to_owned())); -pub const RP_ORIGIN: Lazy = +pub static RP_ORIGIN: Lazy = Lazy::new(|| env::var("RP_ORIGIN").unwrap_or("http://localhost:8080".to_owned())); -pub const RP_NAME: Lazy = +pub static RP_NAME: Lazy = Lazy::new(|| env::var("RP_NAME").unwrap_or("Localhost".to_owned())); diff --git a/src/entities/mod.rs b/src/entities/mod.rs index 7a9dbb6..7db862b 100644 --- a/src/entities/mod.rs +++ b/src/entities/mod.rs @@ -20,11 +20,11 @@ pub struct ServerState { impl ServerState { pub async fn new() -> Self { // Effective domain name. - let rp_id = RP_ID; + let rp_id = &RP_ID; // Url containing the effective domain name // MUST include the port number! let rp_origin = Url::parse(&RP_ORIGIN).expect("Invalid URL"); - let builder = WebauthnBuilder::new(&rp_id, &rp_origin).expect("Invalid configuration"); + let builder = WebauthnBuilder::new(rp_id, &rp_origin).expect("Invalid configuration"); // Now, with the builder you can define other options. // Set a "nice" relying party name. Has no security properties and diff --git a/src/main.rs b/src/main.rs index 207a95e..dbd8310 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ -use axum::{routing::{get, get_service, post, Route}, Router}; +use axum::{routing::{get, post}, Router}; use entities::*; use services::{auth::{self, finish_authentication, start_authentication}, gc_task, login, login_page, register_page}; @@ -10,7 +10,6 @@ use std::sync::Arc; use tower_cookies::CookieManagerLayer; use tower_http::trace::{self, TraceLayer}; use tower_sessions::{Expiry, MemoryStore, SessionManagerLayer}; -use tower_http::services::{ServeDir, ServeFile}; use tracing::Level; pub mod config; diff --git a/src/services/auth.rs b/src/services/auth.rs index 439efc8..0a46d85 100644 --- a/src/services/auth.rs +++ b/src/services/auth.rs @@ -3,7 +3,6 @@ use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; -use axum::debug_handler; use axum::extract::State; use axum::{ extract::{Json, Path}, @@ -63,12 +62,15 @@ use crate::ServerState; // TODO - Improve error handling and messages fn auth_user(cookie_content: String, session_table: &mut HashMap) -> bool { let Ok(uuid) = Uuid::parse_str(&cookie_content) else { + info!("此用户Session不在表中"); return false; }; let Some(expire) = session_table.get(&uuid) else { + info!("此用户Session已过期"); return false; }; if *expire <= Instant::now() { + info!("此用户Session已过期"); return false; } session_table.insert( @@ -76,7 +78,7 @@ fn auth_user(cookie_content: String, session_table: &mut HashMap) Instant::now() + Duration::from_secs(*SESSION_ACTIVE_TIME), ); tracing::info!("valid cookie {}", uuid); - return true; + true } pub async fn start_register( @@ -188,6 +190,7 @@ pub async fn finish_register( info!("Passkey 正常"); let uid = &user_id.to_string(); let username = &user_name.to_string(); + info!("检查用户是否存在"); // Check if the user_id already exists let record = sqlx::query!("SELECT COUNT(KEY) AS count FROM users WHERE KEY = $1;", uid) .fetch_one(pool) @@ -226,13 +229,14 @@ pub async fn finish_register( .rows_affected() != 1 { + error!("将用户凭据持久化时失败"); return Err(WebauthnError::AuthenticationFailure.to_string()); } StatusCode::OK } Err(e) => { - debug!("challenge_register -> {:?}", e); + error!("challenge_register -> {:?}", e); StatusCode::BAD_REQUEST } }; @@ -277,7 +281,7 @@ pub async fn start_authentication( info!("Start Authentication"); let pool = &state.db; // Remove any previous authentication that may have occurred from the session. - let _ = session.remove::<(Uuid, PasskeyAuthentication)>("auth_state"); + let _ = session.remove::<(Uuid, PasskeyAuthentication)>("auth_state").await; let user_id = sqlx::query!("SELECT KEY FROM users WHERE NAME = $1;", user_name) .fetch_one(pool) .await @@ -342,7 +346,7 @@ pub async fn finish_authentication( .unwrap() .ok_or(WebauthnError::AuthenticationFailure.to_string())?; - let _ = session.remove::<(Uuid, PasskeyAuthentication)>("auth_state"); + let _ = session.remove::<(Uuid, PasskeyAuthentication)>("auth_state").await; let res = match state .webauthn diff --git a/src/services/mod.rs b/src/services/mod.rs index 5ab1896..c02b26b 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -62,7 +62,6 @@ pub async fn auth_otp( pub async fn login( State(state): State>, cookies: Cookies, - Query(params): Query>, Form(frm): Form, ) -> Result { let conn = state.db.acquire().await; @@ -88,14 +87,18 @@ pub async fn login( s, Instant::now() + Duration::from_secs(*SESSION_ACTIVE_TIME), ); + let original_uri = cookies.get("OriginalURL"); let mut new_cookie = Cookie::new(COOKIE_NAME.to_string(), s.to_string()); new_cookie.set_domain(COOKIE_DOMAIN.to_string()); cookies.add(new_cookie); - if let Some(original_uri) = params.get("original_url") { - return Ok(Redirect::to(original_uri)); - } - - return Err((StatusCode::ACCEPTED, "ok")); + // 从Cookie中恢复重定向信息 + let res = match original_uri{ + Some(redirect) => Ok(Redirect::to(redirect.value())), + None => Err((StatusCode::ACCEPTED, "ok")), + }; + // 处理完成重定向后,清除Cookie + cookies.remove(Cookie::new("OriginalURL", "")); + return res; } else { return Err((StatusCode::UNAUTHORIZED, "wrong password")); } @@ -108,22 +111,9 @@ pub async fn login_page(headers: HeaderMap) -> impl IntoResponse { let mut env = Environment::new(); env.add_template("login.html", LOGIN_PAGE_HTML).unwrap(); let template = env.get_template("login.html").unwrap(); - if let Some(original_uri) = headers.get("X-Original-URI") { - if let Ok(uri) = original_uri.to_str() { - tracing::info!("redirect to {}", uri); - if !uri.is_empty() { - let uri = "?original_url=".to_owned() + uri; - return Html( - template - .render(context! { url => uri, home_url => HOME_URL.to_string() }) - .unwrap_or("Error".to_string()), - ); - } - } - } Html( template - .render(context! { url => String::new(), home_url => HOME_URL.to_string() }) + .render(context! { home_url => HOME_URL.to_string() }) .unwrap_or("Error".to_string()), ) }