Cara menggunakan React Router Middleware untuk memperbaiki kerentanan perutean React

 – Beragampengetahuan
7 mins read

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.

Cara menggunakan React Router Middleware untuk memperbaiki kerentanan perutean React

Namun, karena model pemuatan data paralel React Router, pendekatan ini menimbulkan dua masalah arsitektur:

  1. 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.
  2. 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_USER tiba null.
  • Navigasi ke /dashboard/overview.

Anda akan melihat:

Checking auth in dashboard...
❌ Child loader IS RUNNING!
No user, redirecting...
Overview loader found no user.

Log server menunjukkan eksekusi pemuat paralel

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

Log perangkat tengah

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:

  1. Kunjungi untuk mendapatkan ID aplikasi

  2. 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>
                        

  3. (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

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *