feat(auth): add Secure flag to session cookie via COOKIE_SECURE env
This commit is contained in:
parent
a070e3f8fc
commit
4ae7b38131
@ -229,10 +229,7 @@ pub async fn login(username: String, password: String) -> Result<AuthResponse, S
|
||||
.await
|
||||
.map_err(AppError::query)?;
|
||||
|
||||
let cookie = format!(
|
||||
"session={token}; HttpOnly; Path=/; Max-Age={}; SameSite=Lax",
|
||||
30 * 24 * 60 * 60
|
||||
);
|
||||
let cookie = session::session_cookie(&token, 30 * 24 * 60 * 60, session::cookie_secure());
|
||||
if let Some(ctx) = dioxus::fullstack::FullstackContext::current() {
|
||||
if let Ok(value) = HeaderValue::try_from(cookie.as_str()) {
|
||||
ctx.add_response_header(SET_COOKIE, value);
|
||||
@ -252,11 +249,11 @@ pub async fn logout() -> Result<AuthResponse, ServerFnError> {
|
||||
|
||||
let client = get_conn().await.map_err(AppError::db_conn)?;
|
||||
|
||||
let cookie = session::session_cookie("", 0, session::cookie_secure());
|
||||
if let Some(ctx) = dioxus::fullstack::FullstackContext::current() {
|
||||
ctx.add_response_header(
|
||||
SET_COOKIE,
|
||||
HeaderValue::from_static("session=; HttpOnly; Path=/; Max-Age=0; SameSite=Lax"),
|
||||
);
|
||||
if let Ok(value) = HeaderValue::try_from(cookie.as_str()) {
|
||||
ctx.add_response_header(SET_COOKIE, value);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(t) = token {
|
||||
|
||||
@ -19,6 +19,22 @@ pub fn default_expiry() -> DateTime<Utc> {
|
||||
Utc::now() + Duration::days(30)
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub fn cookie_secure() -> bool {
|
||||
std::env::var("COOKIE_SECURE")
|
||||
.ok()
|
||||
.map(|v| matches!(v.as_str(), "1" | "true" | "yes"))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub fn session_cookie(token: &str, max_age_seconds: i32, secure: bool) -> String {
|
||||
let secure_flag = if secure { "; Secure" } else { "" };
|
||||
format!(
|
||||
"session={token}; HttpOnly; Path=/; Max-Age={max_age_seconds}; SameSite=Lax{secure_flag}"
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub fn parse_session_token(cookie_header: &str) -> Option<&str> {
|
||||
cookie_header.split(';').map(|s| s.trim()).find_map(|pair| {
|
||||
@ -132,4 +148,25 @@ mod tests {
|
||||
let expected = sha2::Sha256::digest(b"hello");
|
||||
assert_eq!(hash, hex::encode(expected));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_cookie_without_secure() {
|
||||
let cookie = session_cookie("abc", 3600, false);
|
||||
assert!(cookie.contains("session=abc"));
|
||||
assert!(cookie.contains("HttpOnly"));
|
||||
assert!(cookie.contains("SameSite=Lax"));
|
||||
assert!(!cookie.contains("Secure"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_cookie_with_secure() {
|
||||
let cookie = session_cookie("abc", 3600, true);
|
||||
assert!(cookie.contains("Secure"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_cookie_logout_has_zero_max_age() {
|
||||
let cookie = session_cookie("", 0, false);
|
||||
assert!(cookie.contains("Max-Age=0"));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user