Auth

TsgcHTMLAuth : sessions côté serveur, état de connexion et protection CSRF pour une application sgcHTML, en Delphi, C++ Builder et .NET.

TsgcHTMLAuth

Un composant non visuel qui possède le cookie de session, l'utilisateur connecté et le jeton CSRF de chaque requête. Affectez un magasin de sessions, gérez OnAuthenticate pour vérifier le mot de passe, définissez la propriété Auth du moteur HTMX et marquez les routes avec RequireLogin. Il fait partie de sgcHTML, qui est vendu indépendamment, comme pack autonome.

Classe du composant

TsgcHTMLAuth avec TsgcHTMLSessionStore_Memory, TsgcHTMLSessionStore_File et TsgcHTMLSession (unités sgcHTML_Auth et sgcHTML_Session)

Produit

Aucun balisage : cookies de session, jetons CSRF et redirections de connexion

Langages

Delphi, C++ Builder, .NET

Créez un magasin, créez l'Auth, protégez une route

Affectez un magasin de sessions, gérez OnAuthenticate, définissez Auth sur le moteur et marquez les routes à protéger. À partir de là, le moteur lit la session de chaque requête, vérifie le jeton CSRF et redirige les utilisateurs anonymes vers 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");

Propriétés & méthodes clés

Les membres que vous utilisez le plus souvent.

CookieName (sgcsid par défaut), CookiePath et CookieDomain définissent le cookie. CookieSecure et CookieHttpOnly valent True par défaut et CookieSameSite vaut hssLax ; hssStrict et hssNone sont les autres valeurs, et hssNone ajoute toujours Secure.

Délais d'expiration

IdleTimeout (1800 secondes) met fin à une session inutilisée, AbsoluteTimeout (43200 secondes) y met fin après ce délai depuis la connexion, quelle que soit l'activité. 0 désactive l'une ou l'autre vérification. CurrentSession valide les deux et actualise la session à chaque requête.

Jetons CSRF

CSRFProtection est activé par défaut. Chaque session reçoit un jeton aléatoire : IssueCSRF(session) le renvoie et ValidateCSRF(session, token) le compare en temps constant. Le moteur lit le jeton dans l'en-tête CSRFHeaderName (X-CSRF-Token) ou dans le champ CSRFFieldName (csrf_token) et répond 403 à une requête qui modifie l'état et n'en comporte pas.

CSRF avec htmx

Une page rendue pour une session connectée porte <meta name="csrf-token"> et <meta name="csrf-header"> dans son en-tête, et le script htmx fourni envoie le jeton dans cet en-tête à chaque requête qui n'est pas GET, HEAD ou OPTIONS. hx-post et hx-delete n'ont besoin d'aucun balisage supplémentaire.

Se souvenir de moi

RememberMeDays (0 signifie désactivé, 3650 au maximum) l'active et RememberCookieName nomme le cookie (sgcrem). Lorsqu'une requête n'a pas de session valide mais un jeton valide, OnLoadUser recharge l'utilisateur, une nouvelle session est émise et le jeton est renouvelé. Le magasin ne conserve qu'un hachage du vérificateur.

Limitation des tentatives de connexion

LoginRateLimit est un TsgcHTMLAuthRateLimit_Options. Les connexions échouées sont comptées par IP cliente et par nom d'utilisateur dans la fenêtre WindowSeconds (300) ; atteindre MaxAttempts (5) verrouille cette IP ou cet utilisateur pendant LockoutSeconds (900), et OnAuthenticate n'est pas appelé tant que le verrou est actif. MaxAttempts = 0 désactive la limite et IsLoginLocked(ip, user) signale un verrouillage.

Mots de passe

sgcHTMLPasswordHash(password, iterations) renvoie pbkdf2-sha256$iterations$salt$hash avec un sel aléatoire de 16 octets et 210000 itérations par défaut. sgcHTMLPasswordVerify(password, hash) vérifie un mot de passe en temps constant et renvoie False pour un hachage mal formé.

Magasins de sessions

TsgcHTMLSessionStore_Memory conserve les sessions dans le processus, avec SweepInterval pour un nettoyage en arrière-plan ; gardez ses IdleTimeout et AbsoluteTimeout égaux à ceux de l'Auth. TsgcHTMLSessionStore_File écrit un fichier JSON par session dans Folder, de sorte que plusieurs processus peuvent le partager, et réécrit un fichier au plus toutes les TouchInterval secondes (60). Les deux sont thread-safe.

La session

TsgcHTMLSession contient ID, UserID, DisplayName, Roles, des Values libres (nom=valeur), CSRFToken, CreatedAt, LastSeen, RemoteIP et UserAgentHash, plus HasRole. Une route la lit comme TsgcHTMXRequest.Session, nil si anonyme. Les magasins remettent des copies, appelez donc SessionStore.Put pour conserver une modification.

Connexion et déconnexion

Authenticate applique la limite de tentatives et déclenche OnAuthenticate. SignIn crée toujours un nouvel identifiant de session, supprime l'ancien et émet un nouveau jeton CSRF, ce qui protège contre la fixation de session. SignOut met fin à une session et SignOutEverywhere(userID) met fin à toutes les sessions et à tous les jetons « se souvenir de moi » d'un utilisateur. En dehors du moteur, appelez vous-même CurrentSession(cookieHeader, remoteIP, userAgent, setCookies), comme le fait la démo Admin CRUD.

Protection des routes

Marquez une TsgcHTMX_Route avec RequireLogin ou RequireRoles (séparés par des virgules, une seule correspondance suffit). Une requête anonyme est redirigée vers LoginPath?next= avec un 302, ou reçoit 401 plus HX-Redirect lorsqu'elle vient de htmx ; une session sans le rôle reçoit 403. Le moteur répond aussi aux POST vers LoginPath et LogoutPath, puis redirige vers AfterLoginPath.

Connexions WebSocket

Un message s'exécute avec la session des cookies envoyés lors du handshake WebSocket, à condition que ce handshake provienne de la même origine ; tout autre message est anonyme, et un message refusé ne reçoit aucune réponse. TsgcHTMX_Engine_Server.MessageSession(aConnection) renvoie la session derrière une connexion pour un hôte qui répond lui-même à OnHTMXMessage, et l'appelant la libère.

Continuez l'exploration

Aide en ligneRéférence API complète et guide d’utilisation pour ce composant.
Guide des sessions et de l'authentificationCookies, CSRF, protection des routes, « se souvenir de moi » et limitation des tentatives de connexion, pas à pas.
Tous les composants sgcHTMLParcourez la matrice complète des fonctionnalités de plus de 80 composants.
Télécharger la version d'essai gratuiteLa version d'essai de 30 jours fournit les projets de démonstration 60.HTML, dont 02.AdminCRUD, qui se connecte via TsgcHTMLAuth.
TarifsLicences Single, Team et Site avec code source complet.
Meilleur rapport qualité-prix : All-AccessTous les produits eSeGeCe, Support Premium inclus, à partir de €1,059/an.
Voir les tarifs All-Access

Prêt à démarrer ?

Téléchargez la version d'essai gratuite et commencez à créer des interfaces web en Delphi, C++ Builder et .NET.