use axum_extra::extract::cookie::{Cookie, CookieJar, SameSite}; use rand::{distributions::Alphanumeric, Rng}; const CSRF_COOKIE: &str = "csrf_token"; pub fn generate_token() -> String { rand::thread_rng() .sample_iter(&Alphanumeric) .take(32) .map(char::from) .collect() } pub fn ensure_csrf_cookie(jar: CookieJar) -> (CookieJar, String) { if let Some(cookie) = jar.get(CSRF_COOKIE) { let token = cookie.value().to_string(); if token.len() >= 32 { return (jar, token); } } let token = generate_token(); let cookie = Cookie::build((CSRF_COOKIE, token.clone())) .http_only(true) .same_site(SameSite::Strict) .path("/") .build(); (jar.add(cookie), token) } pub fn validate_csrf(jar: &CookieJar, token: &str) -> bool { jar.get(CSRF_COOKIE) .map(|c| c.value() == token) .unwrap_or(false) }