Rediriger les utilisateurs non authentifiés, AWS Amplify
P粉533898694
P粉533898694 2023-09-09 11:27:06
0
2
686

J'essaie de créer une application Web à l'aide d'AWS Amplify. J'ai configuré l'authentification mais je souhaite que certaines pages ne soient disponibles que pour les utilisateurs authentifiés, par exemple la page d'accueil peut être vue par n'importe qui mais "/dashboard" ne peut être vu que par les utilisateurs connectés. J'utilise actuellement AWS Amplify pour mon backend et un frontend React, en utilisant React-Router v6 pour acheminer entre les pages.

Actuellement, mon code de routage est très simple (c'est la première fois que j'utilise React) et se trouve dans App.js :

import React from 'react';
import {
  BrowserRouter,
  Route,
  Routes,
} from 'react-router-dom';

import Login from './pages/Login';
import Home from './pages/Home';
import Dashboard from './pages/Dashboard';
import ErrorPage from './pages/ErrorPage';

const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route exact path="/" element={<Home />} />
        <Route path="/login" element={<Login />} />
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="*" element={<ErrorPage />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

J'ai d'abord essayé d'utiliser withAuthenticator pour envelopper la page que je voulais authentifier, mais cela a simplement abouti à une boucle affichant la boîte de connexion.

function Dashboard({ signOut, user }) {
  return (
    <>
      <h1>Hello {user.username}, this is still in development.</h1>
      <button onClick={signOut}> Sign out</button>
    </>
  );
}

export default withAuthenticator(Dashboard);

J'ai également essayé d'ajouter une fonction pour vérifier si l'utilisateur est authentifié et renvoyer quelque chose de différent, mais cela n'affiche qu'un écran vide pour les utilisateurs authentifiés et non authentifiés. Je pense que c'est parce que c'est le cas async, mais je ne connais pas suffisamment React pour comprendre pourquoi et comment y remédier.

async function isAuthed() {
  try {
    await Auth.currentAuthenticatedUser();
    return true;
  } catch(e) {
    return false;
  }
}

async function Dashboard() {
  if (await isAuthed()) {
    return (
      <>
        <h1>Hello, this is still in development.</h1>
      </>
    );
  } else {
    return (
      <>
        <h1>Please login to view this page.</h1>
      </>
    )
  }
}

J'ai également essayé de voir s'il existait un moyen d'acheminer de manière asynchrone, mais je ne sais pas comment l'implémenter.

Éditeur :

La solution de

@Jlove fonctionne déjà comme prévu, mon App.jscode de routage mis à jour est le suivant :

import React, { useState, useEffect } from 'react';
import {
  BrowserRouter,
  Route,
  Routes,
  useNavigate,
} from 'react-router-dom';
import { Amplify, Auth } from 'aws-amplify'

import Login from './pages/Login';
import Home from './pages/Home';
import Dashboard from './pages/Dashboard';
import ErrorPage from './pages/ErrorPage';
import Unauthenticated from './pages/Unauthenticated';

function RequireAuth({ children }) {
  const navigate = useNavigate();
  const [isAuth, setIsAuth] = useState(null);

  useEffect(() => {
    Auth.currentAuthenticatedUser()
      .then(() => setIsAuth(true))
      .catch(() => {
        navigate("/unauthenticated")
      })
  }, [])
    
  return isAuth && children;
}

const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route exact path="/" element={<Home />} />
        <Route path="/login" element={<Login />} />
        <Route
          path="/dashboard" 
          element={
            <RequireAuth>
              <Dashboard />
            </RequireAuth>
          }
        />
        <Route path="*" element={<ErrorPage />} />
        <Route path="/unauthenticated" element={<Unauthenticated />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

P粉533898694
P粉533898694

répondre à tous(2)
P粉725827686

Vous souhaiterez séparer la logique qui protège vos itinéraires de ce que chaque itinéraire restitue. Ne mélangez pas l'authentification avec les composants d'interface utilisateur/de contenu que vous souhaitez afficher sur l'itinéraire.

Un modèle de protection courant consiste à utiliser routage de mise en page pour envelopper l'ensemble du groupe de routes dont vous souhaitez protéger l'accès. Vous allez créer un composant d'itinéraire de mise en page qui déclenche un effet pour vérifier le statut d'authentification de l'utilisateur actuel et renvoyer conditionnellement :

  • Aucun/Chargement (Si le statut n'est pas encore connu)
  • pour les contenus protégésOutlet (si l'utilisateur a été authentifié)
  • Redirection vers un itinéraire non protégé (si l'utilisateur n'est pas authentifié)

Cela empêche (a) l'accès accidentel à une page protégée avant de savoir que l'utilisateur n'est pas authentifié, et (b) la redirection accidentelle vers la page de connexion avant de savoir que l'utilisateur a été authentifié.

Exemple :

const checkAuthentication = async () => {
  try {
    await Auth.currentAuthenticatedUser();
    return true;
  } catch {
    return false;
  }
};
import { Outlet, Navigate } from 'react-router-dom';

const ProtectedRoute = () => {
  const [isAuth, setIsAuth] = useState(undefined);

  useEffect(() => {
    checkAuthentication()
      .then(() => setIsAuth(true))
      .catch(() => setIsAuth(false));
  }, []);

  if (isAuth === undefined) {
    return null; // 或加载中的旋转器/指示器等
  }
    
  return isAuth ? <Outlet /> : <Navigate to="/login" replace />;
}

L’emballage nécessite un routage protégé.

import React from 'react';
import {
  BrowserRouter,
  Route,
  Routes,
} from 'react-router-dom';
import Login from './pages/Login';
import Home from './pages/Home';
import Dashboard from './pages/Dashboard';
import ErrorPage from './pages/ErrorPage';
import ProtectedRoute from './components/ProtectedRoute';

const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/login" element={<Login />} />
        <Route element={<ProtectedRoute />}>
          <Route path="/dashboard" element={<Dashboard />} />
          {/* ... 其他受保护的路由 ... */}
        </Route>
        <Route path="*" element={<ErrorPage />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;
P粉978551081

Voici une façon de procéder en encapsulant le routage des composants dans un composant d'autorisation :

<Route 
    path="/somePathToProtect"
    element={
        <RequireAuth>
            <Dashboard />
        </RequireAuth>
    }
/>

export function RequireAuth({children}) {
    const navigate = useNavigate();

    const [isAuth, setIsAuth] = useState(null);

    useEffect(() => {
        Auth.currentAuthenticatedUser()
            .then(
                () => setIsAuth(true)
            )
            .catch(() => {
                navigate('/routeToCatchNonAuth')
            })
    }, [])

    return isAuth && children;
}

L'objectif ici est d'utiliser le routeur pour diriger les utilisateurs vers des pages non autorisées en fonction de la Auth返回的结果来保护您的路由。如果Authsélection de l'itinéraire de capture.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!