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 models;
|
||||
mod response;
|
||||
|
|
|
|||
|
|
@ -7,3 +7,7 @@ pub struct Login;
|
|||
#[derive(Template)]
|
||||
#[template(path = "home.html")]
|
||||
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 askama::Template;
|
||||
use axum::response::Result;
|
||||
|
|
@ -11,17 +12,22 @@ pub fn router() -> Router {
|
|||
.route("/", get(home_handler))
|
||||
.route("/home", get(home_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> {
|
||||
let access_token = cookies.get("access_token");
|
||||
match access_token {
|
||||
Some(access_token) => {
|
||||
let s = templates::Home {}.render()?;
|
||||
Ok(Html(s))
|
||||
},
|
||||
None => login_handler().await,
|
||||
}
|
||||
pub async fn home_handler(access_token: WebAccessToken) -> Result<Html<String>, RenderError> {
|
||||
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()?;
|
||||
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> {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
<h1>Welcome to the Home Page</h1>
|
||||
<button id="logoutBtn">Logout</button>
|
||||
|
||||
<button id="adminBtn">Admin</button>
|
||||
<script>
|
||||
document
|
||||
.getElementById("logoutBtn")
|
||||
.addEventListener("click", function () {
|
||||
// Remove the cookie by setting its value to an empty string and its expiry date to the past.
|
||||
document.cookie =
|
||||
"access_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||
document.cookie = "access_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||
|
||||
// Redirect to the login page.
|
||||
window.location.href = "/web/login";
|
||||
});
|
||||
|
||||
document
|
||||
.getElementById("adminBtn")
|
||||
.addEventListener("click", function () {
|
||||
// Redirect to the admin page.
|
||||
window.location.href = "/web/admin";
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<body>
|
||||
<h1>Admin Login</h1>
|
||||
<form id="loginForm">
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
// Set the token as a cookie
|
||||
document.cookie =
|
||||
"access_token=" + data.data.access_token + "; path=/";
|
||||
window.location.href = "/";
|
||||
window.location.href = "/web/home";
|
||||
})
|
||||
.catch((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