Authentifizierte Routen

Authentifizierung ist eine extrem häufige Anforderung für Webanwendungen. In dieser Anleitung erfahren Sie, wie Sie TanStack Router verwenden, um geschützte Routen zu erstellen und Benutzer zur Anmeldung weiterzuleiten, wenn sie versuchen, darauf zuzugreifen.

Die Option route.beforeLoad

Die Option route.beforeLoad ermöglicht es Ihnen, eine Funktion anzugeben, die aufgerufen wird, bevor eine Route geladen wird. Sie erhält alle Argumente, die auch die Funktion route.loader erhält. Dies ist ein großartiger Ort, um zu überprüfen, ob ein Benutzer authentifiziert ist, und ihn zur Anmeldeseite weiterzuleiten, wenn er es nicht ist.

Die Funktion beforeLoad wird in relativer Reihenfolge zu diesen anderen Routenladungsfunktionen aufgerufen

  • Routenabgleich (von oben nach unten)
    • route.params.parse
    • route.validateSearch
  • Routenladung (einschließlich Vorabladung)
    • route.beforeLoad
    • route.onError
  • Routenladung (parallel)
    • route.component.preload?
    • route.load

Es ist wichtig zu wissen, dass die Funktion beforeLoad für eine Route vor allen beforeLoad Funktionen ihrer untergeordneten Routen aufgerufen wird. Sie ist im Wesentlichen eine Middleware-Funktion für die Route und alle ihre Kinder.

Wenn Sie in beforeLoad einen Fehler auslösen, wird keine seiner untergeordneten Routen versuchen, geladen zu werden.

Weiterleitung

Obwohl nicht erforderlich, erfordern einige Authentifizierungsabläufe die Weiterleitung zu einer Anmeldeseite. Um dies zu tun, können Sie eine redirect() Funktion auslösen aus beforeLoad

tsx
// src/routes/_authenticated.tsx
export const Route = createFileRoute('/_authenticated')({
  beforeLoad: async ({ location }) => {
    if (!isAuthenticated()) {
      throw redirect({
        to: '/login',
        search: {
          // Use the current location to power a redirect after login
          // (Do not use `router.state.resolvedLocation` as it can
          // potentially lag behind the actual current location)
          redirect: location.href,
        },
      })
    }
  },
})
// src/routes/_authenticated.tsx
export const Route = createFileRoute('/_authenticated')({
  beforeLoad: async ({ location }) => {
    if (!isAuthenticated()) {
      throw redirect({
        to: '/login',
        search: {
          // Use the current location to power a redirect after login
          // (Do not use `router.state.resolvedLocation` as it can
          // potentially lag behind the actual current location)
          redirect: location.href,
        },
      })
    }
  },
})

Tipp

Die Funktion redirect() nimmt alle gleichen Optionen wie die Funktion navigate entgegen, sodass Sie Optionen wie replace: true übergeben können, wenn Sie den aktuellen Verlaufseintrag ersetzen und keinen neuen hinzufügen möchten.

Sobald Sie einen Benutzer authentifiziert haben, ist es auch üblich, ihn zur Seite zurückzuleiten, die er zu öffnen versucht hat. Um dies zu tun, können Sie den Suchparameter redirect nutzen, den wir in unserer ursprünglichen Weiterleitung hinzugefügt haben. Da wir die gesamte URL durch die vorherige ersetzen werden, ist router.history.push hierfür besser geeignet als router.navigate

tsx
router.history.push(search.redirect)
router.history.push(search.redirect)

Nicht-Weiterleitende Authentifizierung

Einige Anwendungen entscheiden sich dafür, Benutzer nicht zu einer Anmeldeseite weiterzuleiten, sondern sie auf derselben Seite zu belassen und ein Anmeldeformular anzuzeigen, das entweder den Hauptinhalt ersetzt oder ihn über ein Modal ausblendet. Dies ist auch mit TanStack Router möglich, indem einfach das Rendern des <Outlet />, das normalerweise die untergeordneten Routen rendern würde, unterbrochen wird.

tsx
// src/routes/_authenticated.tsx
export const Route = createFileRoute('/_authenticated')({
  component: () => {
    if (!isAuthenticated()) {
      return <Login />
    }

    return <Outlet />
  },
})
// src/routes/_authenticated.tsx
export const Route = createFileRoute('/_authenticated')({
  component: () => {
    if (!isAuthenticated()) {
      return <Login />
    }

    return <Outlet />
  },
})

Dies behält den Benutzer auf derselben Seite, erlaubt Ihnen aber dennoch, ein Anmeldeformular zu rendern. Sobald der Benutzer authentifiziert ist, können Sie einfach das <Outlet /> rendern und die untergeordneten Routen werden gerendert.

Authentifizierung mit React Context/Hooks

Wenn Ihr Authentifizierungsfluss auf Interaktionen mit React Context und/oder Hooks angewiesen ist, müssen Sie Ihren Authentifizierungsstatus mit der Option router.context an TanStack Router übergeben.

Wichtig

React Hooks sind nicht dafür gedacht, außerhalb von React-Komponenten verwendet zu werden. Wenn Sie einen Hook außerhalb einer React-Komponente verwenden müssen, müssen Sie den zurückgegebenen Status aus dem Hook in einer Komponente extrahieren, die Ihre <RouterProvider /> umschließt, und dann den zurückgegebenen Wert an TanStack Router übergeben.

Wir werden die Optionen für router.context im Detail im Abschnitt Router Context behandeln.

Hier ist ein Beispiel, das React Context und Hooks zur Sicherung von authentifizierten Routen in TanStack Router verwendet. Sehen Sie die gesamte funktionierende Einrichtung im Beispiel für authentifizierte Routen.

  • src/routes/__root.tsx
tsx
import { createRootRouteWithContext } from '@tanstack/solid-router'

interface MyRouterContext {
  // The ReturnType of your useAuth hook or the value of your AuthContext
  auth: AuthState
}

export const Route = createRootRouteWithContext<MyRouterContext>()({
  component: () => <Outlet />,
})
import { createRootRouteWithContext } from '@tanstack/solid-router'

interface MyRouterContext {
  // The ReturnType of your useAuth hook or the value of your AuthContext
  auth: AuthState
}

export const Route = createRootRouteWithContext<MyRouterContext>()({
  component: () => <Outlet />,
})
  • src/router.tsx
tsx
import { createRouter } from '@tanstack/solid-router'

import { routeTree } from './routeTree.gen'

export const router = createRouter({
  routeTree,
  context: {
    // auth will initially be undefined
    // We'll be passing down the auth state from within a React component
    auth: undefined!,
  },
})
import { createRouter } from '@tanstack/solid-router'

import { routeTree } from './routeTree.gen'

export const router = createRouter({
  routeTree,
  context: {
    // auth will initially be undefined
    // We'll be passing down the auth state from within a React component
    auth: undefined!,
  },
})
  • src/App.tsx
tsx
import { RouterProvider } from '@tanstack/solid-router'

import { AuthProvider, useAuth } from './auth'

import { router } from './router'

function InnerApp() {
  const auth = useAuth()
  return <RouterProvider router={router} context={{ auth }} />
}

function App() {
  return (
    <AuthProvider>
      <InnerApp />
    </AuthProvider>
  )
}
import { RouterProvider } from '@tanstack/solid-router'

import { AuthProvider, useAuth } from './auth'

import { router } from './router'

function InnerApp() {
  const auth = useAuth()
  return <RouterProvider router={router} context={{ auth }} />
}

function App() {
  return (
    <AuthProvider>
      <InnerApp />
    </AuthProvider>
  )
}

Dann können Sie in der authentifizierten Route den Authentifizierungsstatus mithilfe der Funktion beforeLoad überprüfen und eine redirect() Funktion auslösen zu Ihrer Login-Route, wenn der Benutzer nicht angemeldet ist.

  • src/routes/dashboard.route.tsx
tsx
import { createFileRoute, redirect } from '@tanstack/solid-router'

export const Route = createFileRoute('/dashboard')({
  beforeLoad: ({ context, location }) => {
    if (!context.auth.isAuthenticated) {
      throw redirect({
        to: '/login',
        search: {
          redirect: location.href,
        },
      })
    }
  },
})
import { createFileRoute, redirect } from '@tanstack/solid-router'

export const Route = createFileRoute('/dashboard')({
  beforeLoad: ({ context, location }) => {
    if (!context.auth.isAuthenticated) {
      throw redirect({
        to: '/login',
        search: {
          redirect: location.href,
        },
      })
    }
  },
})

Sie können optional auch den Ansatz der Nicht-Weiterleitenden Authentifizierung verwenden, um ein Anmeldeformular anzuzeigen, anstatt einen Redirect aufzurufen.

Dieser Ansatz kann auch in Verbindung mit Pfadlosen oder Layout-Routen verwendet werden, um alle Routen unter ihrer übergeordneten Route zu schützen.

Detaillierte, Schritt-für-Schritt-Implementierungsanleitungen finden Sie unter

Beispiele

Funktionierende Authentifizierungsbeispiele sind im Repository verfügbar

Unsere Partner
Code Rabbit
Netlify
Neon
Clerk
Convex
Sentry
Bytes abonnieren

Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kündbar.

Bytes abonnieren

Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kündbar.