feat: added logging, logout

This commit is contained in:
Fu Zi Xiang 2023-10-11 16:13:13 +08:00
parent c76252be0a
commit 31d1be2469
No known key found for this signature in database
GPG Key ID: 7AE0884D237CEE16
9 changed files with 38 additions and 76 deletions

1
Cargo.lock generated
View File

@ -343,6 +343,7 @@ dependencies = [
"tower", "tower",
"tower-http", "tower-http",
"tower-service", "tower-service",
"tracing",
"uuid", "uuid",
] ]

View File

@ -55,9 +55,7 @@ mime = "0.3.17"
# aws-sdk-s3 = "0.31.1" # aws-sdk-s3 = "0.31.1"
rust-s3 = "0.33.0" rust-s3 = "0.33.0"
redis = "0.23.3" redis = "0.23.3"
tracing = "0.1.37"
# tracing
tracing = { version = "0.1.37" }
tracing-subscriber = { version = "0.3.16", features = ["registry", "env-filter", "ansi", "json"] } tracing-subscriber = { version = "0.3.16", features = ["registry", "env-filter", "ansi", "json"] }
tracing-bunyan-formatter = "0.3.6" tracing-bunyan-formatter = "0.3.6"
tracing-actix-web = "0.7" tracing-actix-web = "0.7"

View File

@ -24,3 +24,4 @@ reqwest = "0.11.22"
tower-service = "0.3.2" tower-service = "0.3.2"
tower-http = { version = "0.4.4", features = ["cors"] } tower-http = { version = "0.4.4", features = ["cors"] }
tower = "0.4.13" tower = "0.4.13"
tracing = "0.1.37"

View File

@ -1,48 +0,0 @@
// use axum::{
// async_trait,
// extract::FromRequestParts,
// http::request::Parts,
// response::{IntoResponse, Redirect},
// };
// use axum_extra::extract::CookieJar;
//
// pub struct WebAccessToken(pub String);
//
// #[async_trait]
// impl<S> FromRequestParts<S> for WebAccessToken
// where
// S: Send + Sync,
// {
// type Rejection = AccessTokenRejection;
//
// async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
// let jar = CookieJar::from_request_parts(parts, state)
// .await
// .map_err(|e| AccessTokenRejection::CookieError(e.to_string()))?;
//
// let token = jar
// .get("access_token")
// .ok_or(AccessTokenRejection::NoAccessToken)?
// .value();
//
// Ok(WebAccessToken(token.to_string()))
// }
// }
//
// #[derive(Clone, Debug)]
// pub enum AccessTokenRejection {
// NoAccessToken,
// CookieError(String),
// }
//
// impl IntoResponse for AccessTokenRejection {
// fn into_response(self) -> axum::response::Response {
// match self {
// AccessTokenRejection::NoAccessToken => Redirect::permanent("/web/login").into_response(),
// AccessTokenRejection::CookieError(err) => {
// println!("cookie error: {}", err);
// Redirect::permanent("/web/login").into_response()
// },
// }
// }
// }

View File

@ -1,4 +1,3 @@
mod access_token;
mod error; mod error;
mod models; mod models;
mod response; mod response;

View File

@ -32,7 +32,7 @@ impl SessionStorage {
match s { match s {
Ok(s) => Some(s), Ok(s) => Some(s),
Err(e) => { Err(e) => {
println!("redis error: {:?}", e); tracing::info!("get user session in redis error: {:?}", e);
None None
}, },
} }
@ -53,7 +53,9 @@ impl SessionStorage {
pub async fn del_user_session(&self, session_id: &str) -> redis::RedisResult<()> { pub async fn del_user_session(&self, session_id: &str) -> redis::RedisResult<()> {
let key = session_id_key(session_id); let key = session_id_key(session_id);
self.redis_client.clone().del::<_, ()>(key).await let res = self.redis_client.clone().del::<_, i64>(key).await?;
tracing::info!("del user session: {} res: {}", session_id, res);
Ok(())
} }
} }
@ -113,7 +115,7 @@ impl IntoResponse for SessionRejection {
match self { match self {
SessionRejection::NoSessionId => Redirect::permanent("/web/login").into_response(), SessionRejection::NoSessionId => Redirect::permanent("/web/login").into_response(),
SessionRejection::CookieError(err) => { SessionRejection::CookieError(err) => {
println!("cookie error: {}", err); tracing::error!("session rejection cookie error: {}", err);
Redirect::permanent("/web/login").into_response() Redirect::permanent("/web/login").into_response()
}, },
SessionRejection::SessionNotFound => Redirect::permanent("/web/login").into_response(), SessionRejection::SessionNotFound => Redirect::permanent("/web/login").into_response(),

View File

@ -32,7 +32,7 @@ pub async fn home_handler(
.await .await
.map(|user_info| user_info.email) .map(|user_info| user_info.email)
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
println!("Failed to fetch user info: {:?}", err); tracing::error!("Error getting user info: {:?}", err);
"".to_owned() "".to_owned()
}); });
@ -55,8 +55,7 @@ pub async fn admin_users_handler(
.await .await
.map_or_else( .map_or_else(
|err| { |err| {
// Log the error and return an empty vector. tracing::error!("Error getting user list: {:?}", err);
println!("Failed to fetch users: {:?}", err);
vec![] vec![]
}, },
|r| r.users, |r| r.users,

View File

@ -17,11 +17,22 @@
.getElementById("logoutBtn") .getElementById("logoutBtn")
.addEventListener("click", function () { .addEventListener("click", function () {
// Remove the cookie by setting its value to an empty string and its expiry date to the past. // Remove the cookie by setting its value to an empty string and its expiry date to the past.
document.cookie = fetch("/web-api/logout", {
"access_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; method: "POST",
headers: {
// Redirect to the login page. "Content-Type": "application/json",
window.location.href = "/web/login"; },
credentials: 'same-origin',
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok' + response.statusText);
}
window.location.href = "/web/login";
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
}); });
document document

View File

@ -41,19 +41,18 @@
body: JSON.stringify(data), body: JSON.stringify(data),
credentials: 'same-origin', credentials: 'same-origin',
}) })
.then((response) => { .then((response) => {
if (!response.ok) { if (!response.ok) {
// If HTTP status code is not OK, throw an error with the status text // If HTTP status code is not OK, throw an error with the status text
throw Error(response.statusText); throw Error(response.statusText);
} }
window.location.href = "/web/home";
window.location.href = "/web/home"; })
}) .catch((error) => {
.catch((error) => { console.error("Error:", error);
console.error("Error:", error); document.getElementById("response").innerText =
document.getElementById("response").innerText = "Login failed: " + error.message;
"Login failed: " + error.message; });
});
}); });
</script> </script>
</body> </body>