Skip to main content
View as Markdown

Atterrissage après connexion

Après la connexion, différents utilisateurs devraient atterrir sur différentes pages — un administrateur sur l'accueil d'administration, un client sur son enregistrement (ou un sélecteur lorsqu'il en a plusieurs). Sovrium exprime cela comme une configuration d'authentification, et non comme une logique de redirection par page : chaque rôle déclare un defaultLanding, le bloc auth déclare un point de montage landingPath, et noAccessPath gère le cas non concordant.

auth:
  strategies:
    - type: emailAndPassword
  scopeTables: [clients]
  defaultRole: customer-admin
  landingPath: /portal
  noAccessPath: /403
  roles:
    - name: engineer
      defaultLanding: /admin
    - name: customer-admin
      defaultLanding: /portal/clients/$currentUser.assignments.clients[0]
      pickerLanding: /portal/select/clients

Champs de configuration

Deux champs sur auth, deux sur chaque rôle :

Champ Niveau Description
landingPath auth Chemin de montage du résolveur de moteur. Les sessions qui naviguent ici sont redirigées vers le defaultLanding du rôle correspondant. Doit commencer par /. Obligatoire dès qu'un rôle définit defaultLanding ou pickerLanding.
noAccessPath auth Chemin de repli lorsqu'aucun defaultLanding de rôle ne correspond à la session. Doit commencer par /. Par défaut /403.
defaultLanding roles[] URL d'atterrissage par rôle. Doit commencer par /. Peut contenir au plus un jeton $currentUser.assignments.<table>[0].
pickerLanding roles[] Repli multi-enregistrements pour un defaultLanding à modèle. Doit commencer par /. Ne doit pas contenir de jeton d'affectation.

Logique de résolution

Lorsqu'une session authentifiée navigue vers auth.landingPath, le moteur parcourt auth.roles[] dans l'ordre de déclaration et applique le premier rôle que l'utilisateur détient. Pour le defaultLanding de ce rôle :

Forme de defaultLanding Nombre d'affectations pour la <table> à modèle Action du moteur
URL simple (sans jeton) s.o. Rediriger vers defaultLanding sans condition.
À modèle (un jeton) Exactement une affectation Substituer l'ID d'affectation, rediriger là.
À modèle (un jeton) Plus d'une affectation Rediriger vers le pickerLanding du rôle.
Aucun rôle concordant / aucune affectation s.o. Rediriger vers noAccessPath (par défaut /403).

Interpolation $currentUser.assignments

Le jeton $currentUser.assignments.<table> se résout en l'ensemble des ID d'enregistrement issus des lignes user_access de l'utilisateur pour <table> (une table de périmètre). Il apparaît de deux manières distinctes :

Dans une URL defaultLanding — la forme à enregistrement unique $currentUser.assignments.<table>[0] substitue le premier ID d'affectation, produisant un lien direct vers cet enregistrement :

roles:
  - name: customer-admin
    defaultLanding: /portal/clients/$currentUser.assignments.clients[0]
    pickerLanding: /portal/select/clients

Un rôle peut contenir au plus un tel jeton (le résolveur ne peut pas déduire quel périmètre compter avec deux). Un pickerLanding ne doit en contenir aucun — par définition, le cas multi-enregistrements n'a pas d'ID unique à substituer.

Dans un dataSource.filter — la forme non indexée $currentUser.assignments.<table> se résout en la liste complète des ID, de sorte que la page de sélection liste exactement les enregistrements que l'utilisateur peut atteindre :

pages:
  - name: client-picker
    path: /portal/select/clients
    access: authenticated
    components:
      - type: list
        props: { id: clients }
        dataSource:
          table: clients
          filter:
            - field: id
              operator: in
              value: $currentUser.assignments.clients
        children:
          - type: text
            content: $record.name

La page landingPath est le garde d'accès

landingPath doit être adossé à une page co-localisée déclarée au même path. Cette page est le garde d'accès non authentifié : son bloc access renvoie les visiteurs anonymes vers /login avant que le résolveur d'atterrissage ne s'exécute. Pour les visiteurs authentifiés, le résolveur redirige avant que cette page (généralement vide) ne soit rendue.

auth:
  landingPath: /portal
  # ...

pages:
  - name: portal-landing
    path: /portal
    access:
      require: authenticated
      redirectTo: /login
    components: [] # never rendered for authed users — resolver redirects first

Exemple complet

auth:
  strategies:
    - type: emailAndPassword
  scopeTables: [clients]
  defaultRole: customer-admin
  landingPath: /portal
  noAccessPath: /403
  roles:
    - name: engineer
      defaultLanding: /admin
    - name: customer-admin
      defaultLanding: /portal/clients/$currentUser.assignments.clients[0]
      pickerLanding: /portal/select/clients

pages:
  - name: portal-landing
    path: /portal
    access: { require: authenticated, redirectTo: /login }
    components: []
  - name: client-detail
    path: /portal/clients/:id
    access: authenticated
    components: []
  - name: client-picker
    path: /portal/select/clients
    access: authenticated
    components: []
  - name: admin-home
    path: /admin
    access: [engineer]
    components: []
  - name: forbidden
    path: /403
    access: authenticated
    components: []

Dans cette application : un engineer atterrit sur /admin ; un customer-admin avec un seul client atterrit sur la page de détail de ce client ; avec plusieurs, sur le sélecteur ; et quiconque que le résolveur ne peut pas placer atteint /403.

Pages associées

  • Rôles & RBAC — là où defaultLanding / pickerLanding sont définis sur les rôles.
  • SessionsscopeTables, user_access et $currentUser.activeAssignment.
  • Pagespath, access et dataSource.filter de page.