feat: implement httpOnly cookie for JWT authentication and update related API calls
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -3,6 +3,20 @@ use jsonwebtoken::{EncodingKey, Header, encode};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Genera el valor del header `Set-Cookie` para el token JWT como httpOnly cookie.
|
||||
/// Usa SameSite=Strict y Secure para producción.
|
||||
pub fn auth_cookie_header(token: &str) -> String {
|
||||
format!(
|
||||
"auth_token={}; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600",
|
||||
token
|
||||
)
|
||||
}
|
||||
|
||||
/// Genera el valor del header `Set-Cookie` para eliminar la cookie de auth.
|
||||
pub fn auth_cookie_clear_header() -> &'static str {
|
||||
"auth_token=; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=0"
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Claims {
|
||||
pub sub: Uuid,
|
||||
@@ -19,7 +33,7 @@ pub fn create_jwt(
|
||||
role: &str,
|
||||
) -> Result<String, jsonwebtoken::errors::Error> {
|
||||
let expiration = Utc::now()
|
||||
.checked_add_signed(Duration::hours(24))
|
||||
.checked_add_signed(Duration::hours(1))
|
||||
.expect("valid timestamp")
|
||||
.timestamp();
|
||||
|
||||
|
||||
@@ -28,17 +28,34 @@ pub async fn org_extractor_middleware(
|
||||
let token = if let Some(token_str) = auth_header.and_then(|s: &str| s.strip_prefix("Bearer ")) {
|
||||
token_str.to_string()
|
||||
} else {
|
||||
// Verificar si hay preview_token en la cadena de consulta
|
||||
let query = req.uri().query().unwrap_or_default();
|
||||
let preview_token = query
|
||||
.split('&')
|
||||
.find(|part| part.starts_with("preview_token="))
|
||||
.and_then(|part| part.split('=').nth(1));
|
||||
// Intentar leer el token desde la httpOnly cookie
|
||||
let cookie_token = req
|
||||
.headers()
|
||||
.get("cookie")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.and_then(|cookie_str| {
|
||||
cookie_str.split(';').find_map(|part| {
|
||||
let part = part.trim();
|
||||
part.strip_prefix("auth_token=")
|
||||
})
|
||||
})
|
||||
.map(|t| t.to_string());
|
||||
|
||||
if let Some(token) = preview_token {
|
||||
token.to_string()
|
||||
if let Some(token) = cookie_token {
|
||||
token
|
||||
} else {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
// Verificar si hay preview_token en la cadena de consulta
|
||||
let query = req.uri().query().unwrap_or_default();
|
||||
let preview_token = query
|
||||
.split('&')
|
||||
.find(|part| part.starts_with("preview_token="))
|
||||
.and_then(|part| part.split('=').nth(1));
|
||||
|
||||
if let Some(token) = preview_token {
|
||||
token.to_string()
|
||||
} else {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user