34 lines
933 B
Rust
34 lines
933 B
Rust
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)
|
|
}
|