React SDK (@auris/react)
@auris/react v0.1.0@auris/react stellt React-Bindings für Auris IAM bereit. Es umhüllt @auris/js mit einem Context-Provider, Hooks für den Zugriff auf den Authentifizierungsstatus, Berechtigungs-Checks, FGA-Abfragen und Organisations-Kontext — plus vorgefertigte UI-Komponenten für häufige Muster.
Installation
npm install @auris/react @auris/jsBeide Pakete sind erforderlich. @auris/react hängt von @auris/js als Peer-Dependency ab.
AurisProvider
Die Anwendungswurzel (oder den Teilbaum, der Authentifizierung benötigt) mit AurisProvider umhüllen. Er initialisiert den AurisClient, stellt eine vorhandene Sitzung aus dem Speicher wieder her und stellt den Auris-Kontext allen untergeordneten Komponenten bereit.
import { AurisProvider } from '@auris/react'
function App() {
return (
<AurisProvider
domain="auth.yourdomain.com"
clientId="app_xxxxx"
redirectUri="http://localhost:3000/callback"
tenant="my-tenant"
storage="localStorage"
autoRefresh={true}
>
<YourApp />
</AurisProvider>
)
}Props:
| Prop | Typ | Erforderlich | Standard | Beschreibung |
|---|---|---|---|---|
domain | string | Ja | — | Dein Auris-Tenant-Domain |
clientId | string | Ja | — | Anwendungs-Client-ID |
redirectUri | string | Bedingt | — | Callback-URL für PKCE-Flows |
tenant | string | Nein | 'default' | Tenant-Bezeichner |
storage | string | TokenStore | Nein | 'localStorage' | Token-Speicherstrategie |
autoRefresh | boolean | Nein | true | Tokens automatisch erneuern |
scope | string | Nein | 'openid profile email' | Anzufordernde OAuth2-Scopes |
onRedirectCallback | (result: AuthResult) => void | Nein | — | Wird nach erfolgreichem handleRedirectCallback() aufgerufen |
In einer Next.js-Anwendung AurisProvider aus @auris/nextjs importieren, nicht aus @auris/react. Das Next.js-Paket re-exportiert alle React-Komponenten und Hooks.
Hooks
useAuris()
Der primäre Hook. Gibt den vollständigen Authentifizierungskontext zurück: aktueller Benutzer, Ladezustand, Auth-Methoden und Fehlerinformationen.
Gibt zurück:
interface AurisContextValue {
// Zustand
user: UserInfo | null
isLoading: boolean
isAuthenticated: boolean
error: AurisError | null
// Auth-Methoden
login: (email: string, password: string) => Promise<AuthResult>
signup: (email: string, password: string, options?: SignupOptions) => Promise<AuthResult>
logout: (options?: LogoutOptions) => Promise<void>
loginWithRedirect: (options?: LoginWithRedirectOptions) => Promise<void>
handleRedirectCallback: () => Promise<AuthResult>
loginWithMagicLink: (email: string) => Promise<void>
verifyMagicLink: (token: string) => Promise<AuthResult>
loginWithSocial: (provider: SocialProvider) => Promise<void>
refreshToken: () => Promise<AuthResult>
// Token-Zugriff
getAccessToken: () => Promise<string | null>
}import { useAuris } from '@auris/react'
function UserMenu() {
const { user, isLoading, isAuthenticated, loginWithRedirect, logout } = useAuris()
if (isLoading) return <div>Lädt...</div>
if (!isAuthenticated) {
return <button onClick={loginWithRedirect}>Anmelden</button>
}
return (
<div>
<span>{user.name}</span>
<button onClick={() => logout({ returnTo: window.location.origin })}>Abmelden</button>
</div>
)
}useUser()
Ein fokussierter Hook, der nur den aktuellen Benutzer und seinen Ladezustand zurückgibt.
import { useUser } from '@auris/react'
function Avatar() {
const { user, isLoading } = useUser()
if (isLoading) return <div className="avatar-skeleton" />
if (!user) return null
return (
<img
src={user.picture ?? `https://ui-avatars.com/api/?name=${user.name}`}
alt={user.name}
/>
)
}useAccessToken()
Gibt den aktuellen Access-Token-String zurück. Erneuert das Token automatisch, wenn es abgelaufen ist und autoRefresh aktiviert ist.
import { useAccessToken } from '@auris/react'
function useAuthenticatedFetch() {
const { token } = useAccessToken()
return async function fetch(url: string, init?: RequestInit) {
return window.fetch(url, {
...init,
headers: {
...init?.headers,
Authorization: `Bearer ${token}`,
},
})
}
}usePermissions(permissions)
Überprüft, ob der aktuelle Benutzer eine oder alle angegebenen Berechtigungen hat.
Signatur:
usePermissions(permissions: string[]): UsePermissionsResultimport { usePermissions } from '@auris/react'
function AdminActions() {
const { has, hasAny, isLoading } = usePermissions(['manage:users', 'delete:content'])
if (isLoading) return <Spinner />
return (
<div>
{has('manage:users') && <button>Benutzer verwalten</button>}
{has('delete:content') && <button>Inhalte löschen</button>}
{!hasAny && <p>Du hast keine Berechtigung für Admin-Aktionen.</p>}
</div>
)
}useCheckPermission(permission)
Überprüft eine einzelne Berechtigung. Einfacher als usePermissions() bei nur einem Check.
import { useCheckPermission } from '@auris/react'
function DeleteButton({ documentId }: { documentId: string }) {
const { allowed, isLoading } = useCheckPermission('delete:documents')
if (isLoading || !allowed) return null
return (
<button onClick={() => deleteDocument(documentId)}>Löschen</button>
)
}useOrganization()
Gibt den aktuellen Organisations-Kontext für B2B-Multi-Tenant-Anwendungen zurück.
import { useOrganization } from '@auris/react'
function OrgHeader() {
const { organization, isLoading } = useOrganization()
if (isLoading || !organization) return null
return (
<div>
{organization.logoUrl && <img src={organization.logoUrl} alt={organization.name} />}
<h1>{organization.name}</h1>
</div>
)
}useFga()
Zugriff auf Fine-Grained Authorization Checks aus einer React-Komponente.
import { useFga, useUser } from '@auris/react'
function DocumentActions({ documentId }: { documentId: string }) {
const { user } = useUser()
const { check } = useFga()
const [canEdit, setCanEdit] = React.useState(false)
React.useEffect(() => {
if (!user) return
check({
objectType: 'document',
objectId: documentId,
relation: 'editor',
subjectType: 'user',
subjectId: user.id,
}).then((r) => setCanEdit(r.allowed))
}, [user, documentId])
return canEdit ? <button>Bearbeiten</button> : null
}Komponenten
AuthGuard
Umhüllt einen Teilbaum und leitet nicht authentifizierte Benutzer zur Login-Seite weiter. Während der Authentifizierungsstatus geladen wird, rendert die fallback-Prop (oder nichts).
Props:
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
loginUrl | string | '/login' | URL für nicht authentifizierte Benutzer |
fallback | React.ReactNode | null | Wird während des Ladens gerendert |
children | React.ReactNode | — | Inhalte für authentifizierte Benutzer |
import { AuthGuard } from '@auris/react'
function ProtectedPage() {
return (
<AuthGuard loginUrl="/auth/login" fallback={<PageSkeleton />}>
<h1>Dieser Inhalt erfordert Authentifizierung</h1>
<UserDashboard />
</AuthGuard>
)
}PermissionGate
Rendert seine Kinder bedingt, basierend darauf, ob der aktuelle Benutzer eine bestimmte Berechtigung hat.
Props:
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
permission | string | — | Zu prüfende Berechtigung (erforderlich) |
fallback | React.ReactNode | null | Wird bei fehlender Berechtigung gerendert |
children | React.ReactNode | — | Wird bei vorhandener Berechtigung gerendert |
import { PermissionGate } from '@auris/react'
function InvoicePage() {
return (
<div>
<h1>Rechnungen</h1>
<InvoiceList />
<PermissionGate
permission="create:invoices"
fallback={<p>Du hast keine Berechtigung, Rechnungen zu erstellen.</p>}
>
<CreateInvoiceButton />
</PermissionGate>
<PermissionGate permission="export:invoices">
<ExportButton />
</PermissionGate>
</div>
)
}LoginButton und LogoutButton
Vorgefertigte Schaltflächen, die loginWithRedirect() bzw. logout() aufrufen.
import { LoginButton, LogoutButton } from '@auris/react'
function Header() {
return (
<nav>
<LoginButton label="Mit Auris anmelden" className="btn btn-primary" />
<LogoutButton returnTo={window.location.origin} label="Abmelden" />
</nav>
)
}Vollständiges Beispiel
Eine vollständige React-SPA mit Login, geschützten Inhalten, Berechtigungs-Gating und Abmeldung:
import React from 'react'
import { AurisProvider, AuthGuard, PermissionGate, useAuris, usePermissions } from '@auris/react'
export default function App() {
return (
<AurisProvider
domain={import.meta.env.VITE_AURIS_DOMAIN}
clientId={import.meta.env.VITE_AURIS_CLIENT_ID}
redirectUri={`${window.location.origin}/callback`}
>
<Router>
<Route path="/" element={<HomePage />} />
<Route path="/callback" element={<CallbackPage />} />
<Route path="/dashboard" element={<DashboardPage />} />
</Router>
</AurisProvider>
)
}
function CallbackPage() {
const { handleRedirectCallback } = useAuris()
const navigate = useNavigate()
React.useEffect(() => {
handleRedirectCallback().then(() => navigate('/dashboard'))
}, [])
return <p>Anmeldung wird abgeschlossen...</p>
}
function DashboardPage() {
return (
<AuthGuard loginUrl="/" fallback={<p>Zugangsdaten werden geprüft...</p>}>
<DashboardContent />
</AuthGuard>
)
}
function DashboardContent() {
const { user, logout } = useAuris()
const { has, isLoading } = usePermissions(['view:reports', 'manage:users'])
return (
<div>
<header>
<h1>Dashboard</h1>
<span>Angemeldet als {user?.email}</span>
<button onClick={() => logout({ returnTo: window.location.origin })}>Abmelden</button>
</header>
<main>
<PermissionGate permission="view:reports">
<ReportsSection />
</PermissionGate>
<PermissionGate
permission="manage:users"
fallback={<p>Du benötigst Admin-Zugriff, um Benutzer zu verwalten.</p>}
>
<UserManagement />
</PermissionGate>
</main>
</div>
)
}Verwandte Seiten
- JavaScript SDK — Zugrunde liegendes SDK mit vollständiger Typreferenz
- Next.js SDK — Serverseitige Helfer und Middleware auf Basis von @auris/react
- Hosted Login Guide — PKCE-Flow-Anleitung
- Berechtigungen — Rollenbasierte Zugriffskontrolle
- FGA Guide — Fine-Grained Authorization