ENbext.dev
DocumentationOutils pour applications

Traduction automatique depuis l’anglais. Consulter l’original.

Sur cette page

Autorisation

@bext-stack/framework/authz répond à une question partout où cela compte : cet utilisateur peut-il faire cette chose sur cette ressource ? Vous déclarez des capacités une fois avec defineGate, puis vérifiez-les dans un loader (porte la page), un action (porte la mutation) ou un composant (affiche ou masque l'interface utilisateur). Il s'agit de l'équivalent pour les développeurs d'applications de la fonctionnalité Rust Politique d'authentification - même idée, TypeScript isolé, indépendant de la forme de l'utilisateur, zéro dépendance.

Si vous connaissez les portes et politiques de Laravel, c'est le même modèle : Gate::define → defineGate, $user->can('update', $post) → gate.allows(user, 'post.update', post), $this->authorize(...) → gate.authorize(...) et un hook before pour un contournement de super-administrateur.

Quand l'utiliser#

  • Gardes de page/itinéraire — refusent une page entière dans son loader.
  • Gardes de mutation — vérifiez un action avant qu'il n'écrive.
  • Interface utilisateur conditionnelle — affiche un bouton ou une section uniquement lorsque cela est autorisé.
  • Menus — créez une navigation à partir de gate.abilities(user).

Revérifiez toujours côté serveur même lorsque l'interface utilisateur cache déjà quelque chose - l'interface utilisateur est une commodité, le chargeur/l'action est l'application.

Conseil

Les capacités reçoivent user | null — un invité est null. Utilisez les assistants à sécurité nulle ( hasRole, hasPermission ) pour qu'un invité ne lance jamais ; un user.role nu le ferait. Les capacités inconnues échouent lorsque est fermé (refusé), donc une faute de frappe dans le nom d'une capacité n'accorde jamais accidentellement l'accès.

Définir une porte#

ts
import { defineGate, hasRole, forbidden } from "@bext-stack/framework/authz";

interface User { id: string; role: "user" | "admin" | "superadmin" }
interface Post { authorId: string }

const gate = defineGate<User>(
  {
    "post.view":   () => true,                                   // public
    "post.update": (u, post: Post) => hasRole(u, "admin") || post.authorId === u?.id,
    "post.delete": (u) => hasRole(u, "admin"),
  },
  { before: (u) => (hasRole(u, "superadmin") ? true : undefined) }, // god-mode bypass
);

Chaque capacité reçoit l'utilisateur (ou null ) ainsi que tous les arguments de ressource, de sorte que les contrôles de propriété se trouvent directement dans la capacité. Le crochet before en option fonctionne en premier et peut court-circuiter toutes les capacités ( true / false ), ou retourner undefined échoue.

L'utiliser#

ts
// In a loader / action — enforce, and 403 if denied:
export async function loader({ request }) {
  const user = await readSession(request);
  if (gate.denies(user, "post.delete")) throw forbidden("admins only");
  return { ... };
}

// In a component — show/hide UI (bind the user once with `for`):
const acl = gate.for(user);
acl.can("post.update", post)     // boolean
acl.cannot("post.delete")        // boolean

// Imperative (services, non-PRISM code) — throws AuthorizationError (403):
gate.authorize(user, "post.update", post);

throw forbidden() renvoie un 403 Response que PRISM affiche comme page interdite. gate.authorize lance un AuthorizationError typé (avec .status = 403 et .toResponse() ) pour le code qui préfère try/catch.

API#

Membre Retours Utiliser
defineGate<U>(abilities?, { before? }) Gate<U> déclarer des capacités + hook global facultatif
gate.define(name, fn) / gate.policy(resource, actions) Gate<U> ajouter des capacités (policy les touches resource.action)
gate.allows(user, ability, ...args) / .denies(...) boolean vérifie l'interface utilisateur et les gardes
gate.authorize(user, ability, ...args) lance AuthorizationError application impérative
gate.for(user) { can, cannot, authorize } lier un utilisateur pour de nombreux contrôles
gate.abilities(user, names?) { ability: boolean } construire un menu / navigation
hasRole(user, ...roles) / hasAllRoles(user, roles) / hasPermission(user, ...perms) boolean prédicats utilisateur à sécurité nulle
forbidden(message?) Response (403) lancer depuis un chargeur/action PRISM

Relation avec la fonctionnalité AuthzPolicy#

La fonctionnalité Rust Politique d'authentification est une couture de politique côté serveur évaluée dans Rust aux limites des requêtes – idéale pour les règles au niveau de l'infrastructure qui doivent être valables quel que soit le cadre d'application en face d'elles. Ce module est le chemin isolé TypeScript pour l'autorisation au niveau de l'application : les règles se trouvent à côté de vos itinéraires et lisent votre propre forme d'utilisateur. Utilisez les deux : des ceintures et des bretelles au bord, des vérifications expressives dans votre code.

Essayez-le#

Le démo de gestion de rôle en direct chasse ses sections membres/administrateurs d'une porte : inversez les rôles et regardez l'interface utilisateur et la revérification côté serveur s'accorder. Source dans sites/demo/src/app/examples/role-gating/page.tsx.

Voir aussi#

Modifier cette page ↗Besoin d’aide ? ↗
Rechercher dans la documentation

Saisissez un sujet, une commande ou une question.