React Academy · บทเรียน

เส้นทางที่มีการป้องกันและตัวตรวจสอบสิทธิ์

เปลี่ยนเส้นทางผู้ใช้ที่ยังไม่ได้ยืนยันตัวตนไปยังหน้าเข้าสู่ระบบด้วยคอมโพเนนต์ตัวห่อหุ้มหรือตัวตรวจสอบจากตัวโหลด

บทเรียน 3 จาก 413 ขั้นตอน

เส้นทางที่มีการป้องกันและตัวตรวจสอบสิทธิ์ เป็นบทเรียน React Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงต้องป้องกันเส้นทาง

บางหน้า เช่น แดชบอร์ด โปรไฟล์ และหน้าผู้ดูแลระบบ ควรเข้าถึงได้เฉพาะผู้ใช้ที่ยืนยันตัวตนแล้ว React Router มีสองแนวทาง ได้แก่ คอมโพเนนต์ครอบและตัวป้องกันที่ใช้ตัวโหลด

โครงสร้างสถานะการยืนยันตัวตน

ขั้นแรก ให้สร้างบริบทการยืนยันตัวตนที่คอมโพเนนต์สามารถอ่านได้ เพื่อทราบว่าผู้ใช้เข้าสู่ระบบแล้วหรือไม่

const AuthContext = React.createContext(null);

function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const login = async (creds) => { const u = await apiLogin(creds); setUser(u); };
  const logout = () => setUser(null);
  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

export const useAuth = () => useContext(AuthContext);

ตัวป้องกันด้วยคอมโพเนนต์ครอบ

สร้างคอมโพเนนต์ PrivateRoute เพื่อตรวจสอบการยืนยันตัวตน และเปลี่ยนเส้นทางไปยังหน้าเข้าสู่ระบบหากผู้ใช้ยังไม่ได้ยืนยันตัวตน

import { Navigate, Outlet } from 'react-router-dom';

function PrivateRoute() {
  const { user } = useAuth();
  if (!user) return <Navigate to="/login" replace />;
  return <Outlet />;
}

// Usage in router:
{ element: <PrivateRoute />, children: [
  { path: '/dashboard', element: <Dashboard /> },
]}

การรักษา URL สำหรับเปลี่ยนเส้นทาง

เก็บ URL ที่ผู้ใช้พยายามเข้าถึงไว้ เพื่อส่งผู้ใช้กลับไปยัง URL นั้นหลังเข้าสู่ระบบ ส่ง URL ดังกล่าวผ่าน state บนคอมโพเนนต์ Navigate

function PrivateRoute() {
  const { user } = useAuth();
  const location = useLocation();
  if (!user) {
    return <Navigate to="/login" state={{ from: location }} replace />;
  }
  return <Outlet />;
}

// In login handler:
const location = useLocation();
const from = location.state?.from?.pathname || '/';
navigate(from, { replace: true });

ตัวป้องกันที่ใช้ตัวโหลด (Data Router)

ใน Data Router API ให้เพิ่มการตรวจสอบการยืนยันตัวตนลงใน loader ของเส้นทาง และโยนการเปลี่ยนเส้นทางหากผู้ใช้ยังไม่ได้ยืนยันตัวตน

import { redirect } from 'react-router-dom';

function requireAuth() {
  const token = localStorage.getItem('token');
  if (!token) throw redirect('/login');
  return token;
}

const router = createBrowserRouter([
  {
    path: '/dashboard',
    loader: requireAuth,
    element: <Dashboard />,
  },
]);

ตัวป้องกันตามบทบาท

ขยายตัวป้องกันให้ตรวจสอบบทบาทด้วย หากผู้ใช้ไม่มีบทบาทที่จำเป็น ให้เปลี่ยนเส้นทางไปยังหน้าที่ไม่ได้รับอนุญาต

function AdminRoute() {
  const { user } = useAuth();
  if (!user) return <Navigate to="/login" replace />;
  if (user.role !== 'admin') return <Navigate to="/unauthorized" replace />;
  return <Outlet />;
}

สถานะกำลังโหลดระหว่างตรวจสอบการยืนยันตัวตน

หากสถานะการยืนยันตัวตนโหลดแบบอะซิงโครนัส (เช่น จากเซิร์ฟเวอร์) ให้แสดงตัวหมุนระหว่างรอการตรวจสอบ เพื่อป้องกันไม่ให้หน้าเข้าสู่ระบบปรากฏขึ้นชั่วขณะ

function PrivateRoute() {
  const { user, isLoading } = useAuth();
  if (isLoading) return <Spinner />;
  if (!user) return <Navigate to="/login" replace />;
  return <Outlet />;
}

การป้องกันหลายเส้นทางพร้อมกัน

จัดกลุ่มเส้นทางที่ต้องป้องกันทั้งหมดไว้ภายใต้ตัวครอบ PrivateRoute เดียว เพื่อไม่ต้องใส่ตัวป้องกันซ้ำในแต่ละเส้นทาง

const router = createBrowserRouter([
  { path: '/login', element: <Login /> },
  {
    element: <PrivateRoute />,
    children: [
      { path: '/dashboard', element: <Dashboard /> },
      { path: '/profile', element: <Profile /> },
      { path: '/settings', element: <Settings /> },
    ],
  },
]);

การจัดการโทเค็นหมดอายุ

ตรวจสอบการหมดอายุของโทเค็นภายในตัวป้องกันหรือตัวดักจับส่วนกลาง และนำผู้ใช้ออกจากระบบเมื่อโทเค็นหมดอายุ จากนั้นเปลี่ยนเส้นทางไปยังหน้าเข้าสู่ระบบ

function isTokenValid(token) {
  const payload = JSON.parse(atob(token.split('.')[1]));
  return payload.exp * 1000 > Date.now();
}

function requireAuth() {
  const token = localStorage.getItem('token');
  if (!token || !isTokenValid(token)) throw redirect('/login');
  return token;
}

กระบวนการใช้โทเค็นรีเฟรช

ก่อนเปลี่ยนเส้นทางเมื่อได้รับ 401 ให้ลองรีเฟรชโทเค็นก่อน และเปลี่ยนเส้นทางไปยังหน้าเข้าสู่ระบบก็ต่อเมื่อการรีเฟรชล้มเหลวด้วย

async function requireAuth() {
  let token = localStorage.getItem('token');
  if (!token || isExpired(token)) {
    token = await refreshToken();
    if (!token) throw redirect('/login');
    localStorage.setItem('token', token);
  }
  return token;
}

การคงสถานะการยืนยันตัวตนหลังโหลดใหม่

เก็บโทเค็นการยืนยันตัวตนไว้ใน localStorage หรือคุกกี้ HttpOnly เมื่อแอปโหลด ให้กู้คืนสถานะการยืนยันตัวตนก่อนแสดงเส้นทางที่ต้องป้องกัน

ตรวจสอบอย่างรวดเร็ว

เมื่อใช้ตัวป้องกันการยืนยันตัวตนด้วยตัวโหลดใน React Router ควรโยนสิ่งใดเพื่อเปลี่ยนเส้นทางผู้ใช้ที่ยังไม่ได้ยืนยันตัวตน

สรุปทบทวน

ป้องกันเส้นทางด้วยตัวครอบ PrivateRoute ที่ใช้ <Outlet /> หรือตัวโหลดที่โยน redirect() เก็บ URL ที่ผู้ใช้ตั้งใจเข้าถึงไว้ในสถานะการเปลี่ยนเส้นทาง จัดการสถานะกำลังโหลดเพื่อป้องกันการแสดงหน้าชั่วขณะ และจัดกลุ่มเส้นทางที่ต้องป้องกันเพื่อหลีกเลี่ยงการเขียนซ้ำ

เริ่มต้นได้ฟรี

เรียนรู้ React ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
88
บทเรียน
324

คำถามที่พบบ่อย

บทเรียน “เส้นทางที่มีการป้องกันและตัวตรวจสอบสิทธิ์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “เส้นทางที่มีการป้องกันและตัวตรวจสอบสิทธิ์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “เส้นทางที่มีการป้องกันและตัวตรวจสอบสิทธิ์”

เปลี่ยนเส้นทางผู้ใช้ที่ยังไม่ได้ยืนยันตัวตนไปยังหน้าเข้าสู่ระบบด้วยคอมโพเนนต์ตัวห่อหุ้มหรือตัวตรวจสอบจากตัวโหลด คุณปฏิบัติ React Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “เส้นทางที่มีการป้องกันและตัวตรวจสอบสิทธิ์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Academy นี้ได้ไหม

ได้ บทเรียน React Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เส้นทางซ้อนกันและเลย์เอาต์ Outlet
  2. ตัวโหลดและแอ็กชัน (Data Router API)
  3. เส้นทางที่มีการป้องกันและตัวตรวจสอบสิทธิ์
  4. การจัดการสถานะในพารามิเตอร์ค้นหาของ URL
← กลับไปที่ React Academy