a simple loginmanager for axum
```rust use std::sync::Arc;
use axum::{ asynctrait, http::request::Parts, middleware::fromextractor, response::{Html, IntoResponse, Redirect, Response}, routing::get, Extension, Form, Router, }; use loginmanager::{AuthContext, AuthUser, CookieSession, CurrentUser, LoginManager}; use sea_orm::{ConnectionTrait, Database, DatabaseBackend, DatabaseConnection, Statement, Value}; use serde::Deserialize;
struct User { id: i32, name: String, password: String, }
impl loginmanager::UserMinix
async fn get_user(id: &Self::Key, req: &mut Parts) -> Option<Self> {
let state = req.extensions.get::<Arc<AppState>>()?;
let user = state
.db()
.query_one(Statement::from_sql_and_values(
DatabaseBackend::Sqlite,
"select id,name,password from user where id=?",
[Value::from(id.to_string())],
))
.await
.ok()??;
let user = Self {
id: user.try_get::<i32>("", "id").unwrap(),
name: user.try_get::<String>("", "name").unwrap(),
password: user.try_get::<String>("", "password").unwrap(),
};
Some(user)
}
fn get_id(&self) -> &Self::Key {
&self.id
}
}
async fn hellouser(AuthUser(user): AuthUser
logout",
user.name
))
.into
async fn login_get() -> impl IntoResponse { return Html( r#"
"#, ); }struct UserForm { username: String, password: String, }
async fn loginpost(
Extension(state): Extension
async fn loginout(
mut authcontext: AuthContext,
CurrentUser(user): CurrentUser
pub struct AppState { conn: DatabaseConnection, }
impl AppState { pub fn db(&self) -> &DatabaseConnection { &self.conn } }
async fn main() {
// protect api
let api = Router::new()
.route("/:path", get(hellouser))
.routelayer(from_extractor::
let loginmanager = LoginManager::new(CookieSession::new(&[8; 32]))
.redirect(true)
.login_view("/login");
let conn: DatabaseConnection = Database::connect("sqlite::memory:").await.unwrap();
conn.execute(Statement::from_string(
DatabaseBackend::Sqlite,
r#"
CREATE TABLE "user" (
"id" INTEGER,
"name" TEXT UNIQUE,
"password" TEXT,
PRIMARY KEY("id")
);
INSERT INTO user VALUES (1,"miku","39"),(2,"miku2","392");
"#
.to_owned(),
))
.await
.unwrap();
let app = Router::new()
.nest("/api", api)
.route("/", get(hello_user))
.route("/login", get(login_get).post(login_post))
.route("/logout", get(login_out))
.route("/common", get(|| async { "Hello, World!" }))
.layer(loginmanager)
.layer(Extension(Arc::new(AppState { conn })));
// run it with hyper on localhost:3000
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
} ```