Auth
TsgcHTMLAuth: sesiones en el servidor, estado de inicio de sesión y protección CSRF para una aplicación sgcHTML, en Delphi, C++ Builder y .NET.
TsgcHTMLAuth: sesiones en el servidor, estado de inicio de sesión y protección CSRF para una aplicación sgcHTML, en Delphi, C++ Builder y .NET.
Un componente no visual que gestiona la cookie de sesión, el usuario autenticado y el token CSRF de cada petición. Asigna un almacén de sesiones, responde a OnAuthenticate para comprobar la contraseña, establece la propiedad Auth del motor HTMX y marca las rutas con RequireLogin. Forma parte de sgcHTML, que se vende de forma independiente como un pack autónomo.
TsgcHTMLAuth con TsgcHTMLSessionStore_Memory, TsgcHTMLSessionStore_File y TsgcHTMLSession (unidades sgcHTML_Auth y sgcHTML_Session)
Sin marcado: cookies de sesión, tokens CSRF y redirecciones de inicio de sesión
Delphi, C++ Builder, .NET
Asigna un almacén de sesiones, responde a OnAuthenticate, establece Auth en el motor y marca las rutas que hay que proteger. A partir de ahí el motor lee la sesión de cada petición, comprueba el token CSRF y redirige a los usuarios anónimos a LoginPath.
uses
sgcHTML_Session, sgcHTML_Auth, sgcHTMX_Router, sgcHTMX_Engine_Server;
// oHTMX is a TsgcHTMX_Engine_Server, oRouter is a TsgcHTMX_Router
var
oStore: TsgcHTMLSessionStore_Memory;
oAuth: TsgcHTMLAuth;
oRoute: TsgcHTMX_Route;
begin
oStore := TsgcHTMLSessionStore_Memory.Create(Self);
oStore.SweepInterval := 60;
oAuth := TsgcHTMLAuth.Create(Self);
oAuth.SessionStore := oStore;
oAuth.IdleTimeout := 1800; // seconds without a request
oAuth.AbsoluteTimeout := 43200; // seconds since sign-in
oAuth.LoginRateLimit.MaxAttempts := 5;
oAuth.OnAuthenticate := AuthAuthenticate;
oHTMX.Auth := oAuth;
// only a signed-in user reaches /orders
oRoute := oRouter.Routes.Add;
oRoute.Path := '/orders';
oRoute.RequireLogin := True;
oRoute.OnRoute := OrdersRoute;
// only a session with one of these roles reaches /admin
oRoute := oRouter.Routes.Add;
oRoute.Path := '/admin';
oRoute.RequireRoles := 'admin,manager';
oRoute.OnRoute := AdminRoute;
end;
procedure TForm1.AuthAuthenticate(Sender: TObject;
const aUser, aPassword: string; var aAccept: Boolean;
var aUserID, aDisplayName: string; const aRoles: TStrings);
begin
// LoadPasswordHash reads the value stored when the user was created
aAccept := sgcHTMLPasswordVerify(aPassword, LoadPasswordHash(aUser));
if aAccept then
begin
aUserID := aUser;
aDisplayName := aUser;
aRoles.Add('admin');
end;
end;
// when you create a user, store this hash, never the password
vHash := sgcHTMLPasswordHash('secret');
// includes: sgcHTML_Session.hpp, sgcHTML_Auth.hpp, sgcHTMX_Router.hpp, sgcHTMX_Engine_Server.hpp
// oHTMX is a TsgcHTMX_Engine_Server, oRouter is a TsgcHTMX_Router
TsgcHTMLSessionStore_Memory *oStore = new TsgcHTMLSessionStore_Memory(this);
oStore->SweepInterval = 60;
TsgcHTMLAuth *oAuth = new TsgcHTMLAuth(this);
oAuth->SessionStore = oStore;
oAuth->IdleTimeout = 1800; // seconds without a request
oAuth->AbsoluteTimeout = 43200; // seconds since sign-in
oAuth->LoginRateLimit->MaxAttempts = 5;
oAuth->OnAuthenticate = AuthAuthenticate;
oHTMX->Auth = oAuth;
// only a signed-in user reaches /orders
TsgcHTMX_Route *oRoute = oRouter->Routes->Add();
oRoute->Path = "/orders";
oRoute->RequireLogin = true;
oRoute->OnRoute = OrdersRoute;
// only a session with one of these roles reaches /admin
oRoute = oRouter->Routes->Add();
oRoute->Path = "/admin";
oRoute->RequireRoles = "admin,manager";
oRoute->OnRoute = AdminRoute;
void __fastcall TForm1::AuthAuthenticate(TObject *Sender,
const UnicodeString aUser, const UnicodeString aPassword, bool &aAccept,
UnicodeString &aUserID, UnicodeString &aDisplayName, TStrings *const aRoles)
{
// LoadPasswordHash reads the value stored when the user was created
aAccept = sgcHTMLPasswordVerify(aPassword, LoadPasswordHash(aUser));
if (aAccept)
{
aUserID = aUser;
aDisplayName = aUser;
aRoles->Add("admin");
}
}
// when you create a user, store this hash, never the password
String hash = sgcHTMLPasswordHash("secret");
using esegece.sgcWebSockets;
// htmx is a TsgcHTMX_Engine_Server, router is a TsgcHTMX_Router
var store = new TsgcHTMLSessionStore_Memory();
store.SweepInterval = 60;
var auth = new TsgcHTMLAuth();
auth.SessionStore = store;
auth.IdleTimeout = 1800; // seconds without a request
auth.AbsoluteTimeout = 43200; // seconds since sign-in
auth.LoginRateLimit.MaxAttempts = 5;
auth.OnAuthenticate += AuthAuthenticate;
htmx.Auth = auth;
// only a signed-in user reaches /orders
var route = router.Routes.Add();
route.Path = "/orders";
route.RequireLogin = true;
route.OnRoute += OrdersRoute;
// only a session with one of these roles reaches /admin
route = router.Routes.Add();
route.Path = "/admin";
route.RequireRoles = "admin,manager";
route.OnRoute += AdminRoute;
void AuthAuthenticate(object sender, string aUser, string aPassword,
ref bool aAccept, ref string aUserID, ref string aDisplayName,
List<string> aRoles)
{
// LoadPasswordHash reads the value stored when the user was created
aAccept = sgcHTMLAuthHelpers.sgcHTMLPasswordVerify(aPassword, LoadPasswordHash(aUser));
if (aAccept)
{
aUserID = aUser;
aDisplayName = aUser;
aRoles.Add("admin");
}
}
// when you create a user, store this hash, never the password
string hash = sgcHTMLAuthHelpers.sgcHTMLPasswordHash("secret");
Los miembros que usarás con más frecuencia.
CookieName (por defecto sgcsid), CookiePath y CookieDomain dan forma a la cookie. CookieSecure y CookieHttpOnly son True por defecto y CookieSameSite es hssLax; hssStrict y hssNone son los otros valores, y hssNone siempre añade Secure.
IdleTimeout (1800 segundos) finaliza una sesión que no se ha usado, AbsoluteTimeout (43200 segundos) la finaliza pasado ese tiempo desde el inicio de sesión, sea cual sea la actividad. 0 desactiva cualquiera de las dos comprobaciones. CurrentSession valida ambas y refresca la sesión en cada petición.
CSRFProtection está activado por defecto. Cada sesión recibe un token aleatorio: IssueCSRF(session) lo devuelve y ValidateCSRF(session, token) lo compara en tiempo constante. El motor lee el token de la cabecera CSRFHeaderName (X-CSRF-Token) o del campo CSRFFieldName (csrf_token) y responde 403 a una petición que modifica el estado y no lo lleva.
Una página renderizada para una sesión autenticada lleva <meta name="csrf-token"> y <meta name="csrf-header"> en su head, y el script htmx incluido envía el token en esa cabecera en toda petición que no sea GET, HEAD ni OPTIONS. hx-post y hx-delete no necesitan marcado adicional.
RememberMeDays (0 significa desactivado, como máximo 3650) lo activa y RememberCookieName da nombre a la cookie (sgcrem). Cuando una petición no tiene una sesión válida pero sí un token válido, OnLoadUser vuelve a cargar el usuario, se emite una sesión nueva y el token se rota. El almacén guarda solo un hash del verificador.
LoginRateLimit es un TsgcHTMLAuthRateLimit_Options. Los inicios de sesión fallidos se cuentan por IP de cliente y por nombre de usuario dentro de WindowSeconds (300); al alcanzar MaxAttempts (5) esa IP o ese usuario queda bloqueado durante LockoutSeconds (900), y no se llama a OnAuthenticate mientras dure el bloqueo. MaxAttempts = 0 desactiva el límite; IsLoginLocked(ip, user) informa de un bloqueo.
sgcHTMLPasswordHash(password, iterations) devuelve pbkdf2-sha256$iterations$salt$hash con un salt aleatorio de 16 bytes y 210000 iteraciones por defecto. sgcHTMLPasswordVerify(password, hash) comprueba una contraseña en tiempo constante y devuelve False para un hash mal formado.
TsgcHTMLSessionStore_Memory guarda las sesiones en el proceso, con SweepInterval para una limpieza en segundo plano; mantén sus IdleTimeout y AbsoluteTimeout iguales a los del Auth. TsgcHTMLSessionStore_File escribe un archivo JSON por sesión en Folder, de modo que varios procesos pueden compartirlo, y reescribe un archivo como máximo cada TouchInterval segundos (60). Ambos son seguros para hilos.
TsgcHTMLSession contiene ID, UserID, DisplayName, Roles, Values libres (nombre=valor), CSRFToken, CreatedAt, LastSeen, RemoteIP y UserAgentHash, además de HasRole. Una ruta la lee como TsgcHTMXRequest.Session, nil cuando es anónima. Los almacenes entregan copias, así que llama a SessionStore.Put para conservar un cambio.
Authenticate aplica el límite de intentos y dispara OnAuthenticate. SignIn siempre crea un id de sesión nuevo, elimina el anterior y emite un token CSRF nuevo, lo que defiende contra la fijación de sesión. SignOut finaliza una sesión y SignOutEverywhere(userID) finaliza todas las sesiones y los tokens de recordarme de un usuario. Fuera del motor, llama tú mismo a CurrentSession(cookieHeader, remoteIP, userAgent, setCookies), como hace la demo Admin CRUD.
Marca un TsgcHTMX_Route con RequireLogin o RequireRoles (separados por comas, basta una coincidencia). Una petición anónima se redirige a LoginPath?next= con un 302, o recibe 401 más HX-Redirect cuando la envió htmx; una sesión sin el rol recibe 403. El motor también responde a POST en LoginPath y LogoutPath, y luego pasa a AfterLoginPath.
Un mensaje se ejecuta con la sesión de las cookies enviadas en el handshake de WebSocket, siempre que ese handshake procediera del mismo origen; cualquier otro mensaje es anónimo, y un mensaje denegado no recibe respuesta. TsgcHTMX_Engine_Server.MessageSession(aConnection) devuelve la sesión que hay tras una conexión para un host que responde a OnHTMXMessage por sí mismo, y quien llama la libera.
| Ayuda en líneaReferencia completa de la API y guía de uso para este componente. | Abrir | |
| Guía de sesiones y autenticaciónCookies, CSRF, control de acceso por ruta, recordarme y el límite de intentos de inicio de sesión, paso a paso. | Abrir | |
| Todos los componentes de sgcHTMLExplora la matriz completa de más de 80 componentes. | Abrir | |
| Descargar prueba gratuitaLa prueba de 30 días incluye los proyectos de demostración 60.HTML, entre ellos 02.AdminCRUD, que inicia sesión mediante TsgcHTMLAuth. | Abrir | |
| PreciosLicencias Single, Team y Site con código fuente completo. | Abrir |