Ubah hala pengguna yang tidak disahkan, AWS Amplify
P粉533898694
P粉533898694 2023-09-09 11:27:06
0
2
736

Saya cuba membina aplikasi web menggunakan AWS Amplify. Saya telah mengkonfigurasi pengesahan tetapi saya mahu halaman tertentu hanya tersedia kepada pengguna yang disahkan, contohnya halaman utama boleh dilihat oleh sesiapa sahaja tetapi "/papan pemuka" hanya boleh dilihat oleh pengguna yang log masuk. Saya sedang menggunakan AWS Amplify untuk bahagian belakang saya dan bahagian hadapan React, menggunakan penghala tindak balas v6 untuk menghala antara halaman.

Pada masa ini kod penghalaan saya sangat mudah (ini kali pertama saya menggunakan React) dan berada dalam 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;

Saya mula-mula mencuba menggunakan withAuthenticator untuk membungkus halaman yang ingin saya sahkan, tetapi ini hanya menghasilkan gelung yang menunjukkan kotak log masuk.

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);

Saya juga cuba menambah fungsi untuk menyemak sama ada pengguna disahkan dan mengembalikan sesuatu yang berbeza, tetapi ini hanya menunjukkan skrin kosong untuk pengguna yang disahkan dan tidak disahkan. Saya rasa ini adalah kerana async, tetapi saya tidak cukup mahir dengan React untuk memahami sebab dan cara membetulkannya.

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>
      </>
    )
  }
}

Saya juga cuba melihat sama ada terdapat cara untuk membuat laluan secara tidak segerak tetapi tidak pasti cara melaksanakannya.

Editor:

@penyelesaian Jlove sudah berfungsi seperti yang diharapkan, kod laluan App.js saya yang dikemas kini adalah seperti berikut:

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

membalas semua(2)
P粉725827686

Anda perlu memisahkan logik yang melindungi laluan anda daripada apa yang ditunjukkan oleh setiap laluan. Jangan campurkan pengesahan dengan komponen UI/kandungan yang anda ingin berikan pada laluan.

Corak perlindungan biasa ialah menggunakan penghalaan reka letak untuk membalut keseluruhan kumpulan laluan yang anda ingin lindungi akses. Anda akan membuat komponen laluan reka letak yang mencetuskan kesan untuk menyemak status pengesahan pengguna semasa dan kembali secara bersyarat:

  • Tiada/Memuatkan (Jika status belum diketahui)
  • untuk kandungan yang dilindungiOutlet (jika pengguna telah disahkan)
  • Ubah hala ke laluan tidak dilindungi (jika pengguna tidak disahkan)

Ini menghalang (a) akses tidak sengaja ke halaman yang dilindungi sebelum diketahui bahawa pengguna tidak disahkan, dan (b) pengalihan tidak sengaja ke halaman log masuk sebelum diketahui bahawa pengguna telah disahkan.

Contoh:

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 />;
}

Pembungkusan memerlukan penghalaan yang dilindungi.

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

Berikut ialah satu cara untuk melakukannya dengan membungkus penghalaan komponen dalam komponen kebenaran:

<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;
}

Matlamat di sini adalah untuk menggunakan penghala untuk menavigasi pengguna ke halaman yang tidak dibenarkan berdasarkan Auth返回的结果来保护您的路由。如果Authmemilih laluan tangkapan.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!