axum_csrf = “0.11.0”
use axum_csrf::{CsrfConfig, CsrfToken};
#[derive(Serialize, Deserialize)]
struct LoginForm {
username: String,
password: String,
authenticity_token: String,
}
#[tokio::main]
async fn main() {
// tracing_subscriber::fmt::init();
let config = CsrfConfig::default();
let serve_dir = ServeDir::new("static").not_found_service(ServeFile::new("static"));
let app = Router::new()
.route("/", get(handle_index))
.route("/login", post(handle_login))
.route("/home", get(handle_home))
.route("/upload", post(handle_upload))
.layer(DefaultBodyLimit::max(1024 * 1024 * 1024))
.nest_service("/static", serve_dir.clone())
.fallback_service(serve_dir)
.with_state(config);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
async fn handle_index(token: CsrfToken) -> impl IntoResponse {
let keys = token.authenticity_token().unwrap();
let tera = tera::Tera::new("templates/*").unwrap();
let mut context = tera::Context::new();
context.insert("title", "Index page");
context.insert("Keys", &keys);
let output = tera.render("test.html", &context);
(token, axum::response::Html(output.unwrap()))
}
async fn handle_login(token: CsrfToken, axum::Form(loginform): axum::Form<LoginForm>)-> axum::response::Html<String> {
if token.verify(&loginform.authenticity_token).is_err() {
println!("Token is invalid");
} else {
println!("Token is Valid lets do stuff!");
}
let username = loginform.username;
let password = loginform.password;
let authenticity_token = loginform.authenticity_token;
println!("username:{}, password:{}, authenticity_token: {}", username, password, authenticity_token);
}
<form method="post" action="/login">
<input type="hidden" name="authenticity_token" value="{{ Keys }}"/>
<div class="mb-3 mt-3">
<input type="text" class="form-control" placeholder="user name" name="username"/>
</div>
<input type="password" class="form-control" placeholder="password" name="password">
<span class="fs-s">If you don't have account, you can <a href="/signup">Sign up</a>.</span><br/>
<input type="submit" class="btn submit" value="login" />
</form>
Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.90s
Running `target/debug/axum`
Token is Valid lets do stuff!
username:asdfggggg, password:asdfggggg, authenticity_token: QnDhKw70YahSelDPpBxJHzgdlXvhFCe2ZKOv+wH82zo=
おおおおおおおおおおおおお、なるほどこれは凄い!!!!
sessionにsession_tokenをセットするロジックを書く方法もありますが、これの方が楽ですね。