extractor for access token
This commit is contained in:
parent
427612b11f
commit
b2450419eb
|
|
@ -0,0 +1,48 @@
|
||||||
|
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)?
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
Ok(WebAccessToken(token))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
mod access_token;
|
||||||
mod error;
|
mod error;
|
||||||
mod models;
|
mod models;
|
||||||
mod response;
|
mod response;
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,7 @@ pub struct Login;
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "home.html")]
|
#[template(path = "home.html")]
|
||||||
pub struct Home;
|
pub struct Home;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(path = "admin.html")]
|
||||||
|
pub struct Admin;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::access_token::WebAccessToken;
|
||||||
use crate::error::RenderError;
|
use crate::error::RenderError;
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use axum::response::Result;
|
use axum::response::Result;
|
||||||
|
|
@ -11,17 +12,22 @@ pub fn router() -> Router {
|
||||||
.route("/", get(home_handler))
|
.route("/", get(home_handler))
|
||||||
.route("/home", get(home_handler))
|
.route("/home", get(home_handler))
|
||||||
.route("/login", get(login_handler))
|
.route("/login", get(login_handler))
|
||||||
|
.route("/admin", get(admin_handler))
|
||||||
|
.route("/admin/users", get(admin_users_handler))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn home_handler(cookies: CookieJar) -> Result<Html<String>, RenderError> {
|
pub async fn home_handler(access_token: WebAccessToken) -> Result<Html<String>, RenderError> {
|
||||||
let access_token = cookies.get("access_token");
|
let s = templates::Home {}.render()?;
|
||||||
match access_token {
|
Ok(Html(s))
|
||||||
Some(access_token) => {
|
}
|
||||||
let s = templates::Home {}.render()?;
|
|
||||||
Ok(Html(s))
|
pub async fn admin_handler(access_token: WebAccessToken) -> Result<Html<String>, RenderError> {
|
||||||
},
|
let s = templates::Admin {}.render()?;
|
||||||
None => login_handler().await,
|
Ok(Html(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn admin_users_handler(cookies: CookieJar) -> Result<Html<String>, RenderError> {
|
||||||
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login_handler() -> Result<Html<String>, RenderError> {
|
pub async fn login_handler() -> Result<Html<String>, RenderError> {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<body>
|
||||||
|
<h1>Welcome to the Admin Page</h1>
|
||||||
|
<button id="usersBtn">Users</button>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document
|
||||||
|
.getElementById("usersBtn")
|
||||||
|
.addEventListener("click", function () {
|
||||||
|
// Redirect to the users page.
|
||||||
|
window.location.href = "/web/admin/users";
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -3,18 +3,24 @@
|
||||||
<body>
|
<body>
|
||||||
<h1>Welcome to the Home Page</h1>
|
<h1>Welcome to the Home Page</h1>
|
||||||
<button id="logoutBtn">Logout</button>
|
<button id="logoutBtn">Logout</button>
|
||||||
|
<button id="adminBtn">Admin</button>
|
||||||
<script>
|
<script>
|
||||||
document
|
document
|
||||||
.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 =
|
document.cookie = "access_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
"access_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
|
||||||
|
|
||||||
// Redirect to the login page.
|
// Redirect to the login page.
|
||||||
window.location.href = "/web/login";
|
window.location.href = "/web/login";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document
|
||||||
|
.getElementById("adminBtn")
|
||||||
|
.addEventListener("click", function () {
|
||||||
|
// Redirect to the admin page.
|
||||||
|
window.location.href = "/web/admin";
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<body>
|
<body>
|
||||||
<h1>Admin Login</h1>
|
<h1>Admin Login</h1>
|
||||||
<form id="loginForm">
|
<form id="loginForm">
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
// Set the token as a cookie
|
// Set the token as a cookie
|
||||||
document.cookie =
|
document.cookie =
|
||||||
"access_token=" + data.data.access_token + "; path=/";
|
"access_token=" + data.data.access_token + "; path=/";
|
||||||
window.location.href = "/";
|
window.location.href = "/web/home";
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error("Error:", error);
|
console.error("Error:", error);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>User List</h1>
|
||||||
|
<ul id="userList"></ul>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
// Fetch the user list from the API
|
||||||
|
fetch('/web-api/users')
|
||||||
|
.then(response => {
|
||||||
|
// Check if HTTP status code indicates success
|
||||||
|
if (!response.ok) {
|
||||||
|
return Promise.reject('Failed to fetch users');
|
||||||
|
}
|
||||||
|
return response.json(); // Parse the JSON response
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
// Display the users on the page
|
||||||
|
const userList = document.getElementById('userList');
|
||||||
|
data.forEach(user => {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.textContent = `${user.name} (${user.email})`;
|
||||||
|
userList.appendChild(li);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('Failed to fetch users');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue