Cara menggunakan React Router Middleware untuk memperbaiki kerentanan perutean React – Beragampengetahuan
Saat mengamankan segmen rute di React Router, pola yang umum adalah menambahkan pemeriksaan otentikasi di dalam rute tata letak loadermisalnya di dashboard.tsx. Pemuat ini biasanya memeriksa sesi pengguna dan memberikan pengecualian redirect('/login') Jika tidak ditemukan.
Namun, karena model pemuatan data paralel React Router, pendekatan ini menimbulkan dua masalah arsitektur:
- Pengalihan kebocoran: subloader (misalnya,
/dashboard/overview) dijalankan secara paralel dengan pemuat induk. Redirect di induk TIDAK Subloader mengalami hubungan pendek, menyebabkan subloader tetap berjalan bahkan tanpa autentikasi. - Akuisisi data yang berlebihan: Karena pemuat berjalan secara paralel, rute anak tidak dapat mengakses data yang dikembalikan oleh pemuat induk. Pemuat induk dapat memperoleh
usertetapi setiap anak harus memperolehnya kembali secara mandiri.
Perilaku ini dapat menyebabkan beban server yang tidak perlu, pengambilan duplikat, dan potensi kesalahan. baru API perangkat tengah Di React Router 7.9+ (melalui future.v8_middleware flag) memecahkan masalah ini dengan memperkenalkan langkah berurutan sebelum eksekusi loader.
Pada artikel ini, kami akan membuat dasbor sederhana untuk mendemonstrasikan masalah “cara lama”, dan kemudian secara bertahap melakukan refaktorisasi menggunakan middleware untuk mengaktifkan autentikasi yang bersih dan pengiriman data yang aman.
Contents
π Berlangganan Buletin Putar Ulang
memutar ulang adalah buletin mingguan untuk para pemimpin pengembangan dan teknik.
Diterbitkan setiap minggu, ini adalah panduan pilihan Anda untuk percakapan paling penting seputar pengembangan front-end, alat AI yang sedang berkembang, dan keadaan perangkat lunak modern.
Masalah: Dashboard Kami Rusak
Pertama-tama kita akan membuat dasbor menggunakan pola pemuat tradisional untuk menampilkan masalahnya. Pertama, buat proyek:
npx create-react-router@latest
di dalam app/buat file autentikasi tiruan:
// app/auth.ts export interface User id: string; name: string; email: string; let FAKE_LOGGED_IN_USER: User | null = null; // let FAKE_LOGGED_IN_USER = id: "123", name: "Jane Doe", email: "[emailΒ protected]" ; export async function getUserFromRequest(request: Request): Promise<User | null> await new Promise((res) => setTimeout(res, 100)); return FAKE_LOGGED_IN_USER;
Struktur rute kami akan terlihat seperti ini:
app/ βββ auth.ts βββ root.tsx βββ routes/ β βββ login.tsx β βββ dashboard.tsx β βββ dashboard.overview.tsx
Sekarang mari kita terapkan tata letak dasbor yang dilindungi:
// app/routes/dashboard.tsx
import Outlet, useLoaderData from "react-router";
import type LoaderFunctionArgs from "react-router";
import getUserFromRequest from "~/auth";
import type User from "~/auth";
export async function loader( request : LoaderFunctionArgs)
console.log("Checking auth in _dashboard layout loader...");
const user = await getUserFromRequest(request);
if (!user)
console.log("No user, redirecting to /login");
// This redirect *should* stop everything, but it won't.
throw Response.redirect(new URL("/login", request.url));
console.log("User found, returning from layout loader.");
return new Response(JSON.stringify( user ),
headers: "Content-Type": "application/json" ,
);
export default function DashboardLayout() Welcome, user!.name
</nav>
<hr />
<main>
<Outlet />
</main>
</div>
);
Berikutnya adalah sub-perutean:
// app/routes/dashboard.overview.tsx
import Outlet, useLoaderData from "react-router";
import type LoaderFunctionArgs from "react-router";
import getUserFromRequest from "~/auth";
async function getOverviewData(userId: string)
console.log(`Fetching overview data for user $userId...`);
return totalRevenue: 5000 ;
export async function loader( request : LoaderFunctionArgs)
console.log("β ERROR: _dashboard.overview loader IS RUNNING!");
// Problem: Redundant data fetching.
const user = await getUserFromRequest(request);
if (!user)
console.log("Overview loader found no user.");
return new Response(JSON.stringify( error: "User not found" ),
status: 401,
headers: "Content-Type": "application/json" ,
);
const overviewData = await getOverviewData(user.id);
return new Response(JSON.stringify(overviewData),
headers: "Content-Type": "application/json" ,
);
export default function DashboardOverview()
return <h3>Overview Page Content</h3>;
Sekarang ulangi masalahnya:
- meletakkan
FAKE_LOGGED_IN_USERtibanull. - Navigasi ke
/dashboard/overview.
Anda akan melihat:
Checking auth in dashboard... β Child loader IS RUNNING! No user, redirecting... Overview loader found no user.

Ini menegaskan:
- mengarahkan kebocoran: Subloader masih berjalan.
- Data diambil dua kali Saat masuk.
Middleware React Router bertujuan untuk menyelesaikan kedua masalah tersebut.
Perbaiki: Gunakan middleware React Router
Langkah 1: Aktifkan bendera middleware
// react-router.config.ts
export default
future:
v8_middleware: true,
,
;
Langkah 2: Buat konteks yang aman untuk tipe
Middleware tidak mengembalikan data secara langsung. Ini menyimpan nilai-nilai bersama dalam konteks:
// app/context.ts import createContext from "react-router"; import type User from "~/auth"; export const userContext = createContext<User | null>(null);
Langkah 3: Perbaiki dasbor yang dilindungi
// app/routes/dashboard.tsx
import Outlet, useLoaderData from "react-router";
import type LoaderFunctionArgs, MiddlewareFunction from "react-router";
import getUserFromRequest from "~/auth";
import type User from "~/auth";
import userContext from "~/context";
const authMiddleware: MiddlewareFunction = async ( request, context ) =>
console.log("Running auth middleware in _dashboard...");
const user = await getUserFromRequest(request);
if (!user)
console.log("Middleware: No user, redirecting to /login");
throw new Response(null,
status: 302,
headers:
"Location": "/login",
,
);
console.log("Middleware: User found, setting in context.");
context.set(userContext, user);
;
export const middleware: MiddlewareFunction[] = [authMiddleware];
export async function loader( context : LoaderFunctionArgs)
const user = context.get(userContext);
console.log("Layout loader running (user guaranteed).");
return new Response(JSON.stringify( user ),
headers: "Content-Type": "application/json" ,
);
export default function DashboardLayout() Welcome, user!.name
</nav>
<hr />
<main>
<Outlet />
</main>
</div>
);
Langkah 4: Verifikasi Hubungan Pendek
Dan FAKE_LOGGED_IN_USER = null:
Running auth middleware... Redirecting to /login

Tidak ada child loader yang beroperasi. Masalah #1 terpecahkan.
Langkah 5: Refaktorkan subloader
// app/routes/dashboard.overview.tsx
import Outlet, useLoaderData from "react-router";
import type LoaderFunctionArgs from "react-router";
import userContext from "~/context";
async function getOverviewData(userId: string)
console.log(`Fetching overview data for user $userId...`);
return totalRevenue: 5000 ;
export async function loader( context : LoaderFunctionArgs)
console.log("β
_dashboard.overview loader IS RUNNING (sequentially)");
const user = context.get(userContext);
const overviewData = await getOverviewData(user!.id);
return new Response(JSON.stringify(overviewData),
headers: "Content-Type": "application/json" ,
);
export default function DashboardOverview()
return <h3>Overview Page Content</h3>;
Outputnya sekarang menunjukkan urutan yang benar:
Running auth middleware... User found, setting context. Layout loader running... Child loader running... Fetching overview data...
sebagai kesimpulan
Kita mulai dengan pola umum di React Router yang dapat dengan mudah menyebabkan kebocoran pengalihan dan pengambilan data yang berlebihan karena eksekusi pemuat paralel. Masalah ini membuat perlindungan rute tidak efisien dan rawan kesalahan.
API middleware baru memperkenalkan langkah berurutan sebelum loader, memungkinkan:
- pengalihan arus pendek sebelum subloader berjalan
- Otentikasi yang aman dan terpusat
- konteks bersama Hilangkan akuisisi duplikat
Middleware akhirnya menyelaraskan React Router dengan keamanan dunia nyata dan kebutuhan pemuatan data, memungkinkan perutean terlindungi yang praktis dan dapat dipelihara.
Hanya perlu beberapa menit untuk menyiapkan pelacakan kesalahan React modern dari beragampengetahuan:
-
Kunjungi untuk mendapatkan ID aplikasi
-
Instal beragampengetahuan melalui npm atau tag skrip.
beragampengetahuan.init()Harus memanggil sisi klien, bukan sisi server$ npm i --save beragampengetahuan // Code: import beragampengetahuan from 'beragampengetahuan'; beragampengetahuan.init('app/id');// Add to your HTML: <script src=" <script>window.beragampengetahuan && window.beragampengetahuan.init('app/id');</script> - (Opsional) Instal plugin untuk integrasi lebih dalam dengan tumpukan Anda:
- Perangkat tengah Redux
- Perangkat tengah NgRx
- Plugin Vuex
Mulai sekarang
rencana pengembangan website
metode pengembangan website
jelaskan beberapa rencana untuk pengembangan website, proses pengembangan website, kekuatan dan kelemahan bisnis pengembangan website
, jasa pengembangan website, tahap pengembangan website, biaya pengembangan website
#Cara #menggunakan #React #Router #Middleware #untuk #memperbaiki #kerentanan #perutean #React