Đôi điều về Hook useAuth trong React

0 0 0

Người đăng: Gung Typical

Theo Viblo Asia

Xác thực (Authentication) và phân quyền (Authorization) là những yếu tố quan trọng trong các ứng dụng web. Thay vì xử lý chúng thủ công trong nhiều thành phần (components), chúng ta có thể tạo một hook có thể tái sử dụng để đơn giản hóa logic.

Trong bài viết này, chúng ta sẽ triển khai logic xác thực trực tiếp trong một component trước, sau đó sẽ refactor (tái cấu trúc) nó bằng cách sử dụng hook useAuth tùy chỉnh.

Logic xác thực không có Hook tùy chỉnh

Hãy bắt đầu bằng cách tạo một thành phần React để quản lý xác thực người dùng theo cách thủ công.

import React, { useState } from "react"; const AuthComponent = () => { const [user, setUser] = useState(null); const login = (username) => { setUser({ name: username, role: "user" }); }; const logout = () => { setUser(null); }; return ( <div> {user ? ( <> <h2>Welcome, {user.name}!</h2> <button onClick={logout}>Logout</button> </> ) : ( <button onClick={() => login("John Doe")}>Login</button> )} </div> );
}; export default AuthComponent;

Các vấn đề với cách tiếp cận này

  • Logic xác thực bị ràng buộc với một thành phần duy nhất, khiến việc tái sử dụng trở nên khó khăn.
  • Không có cách tập trung nào để quản lý trạng thái người dùng trên toàn bộ ứng dụng.
  • Kiểm tra quyền hạn cần phải được thực hiện thủ công trong nhiều thành phần.

Tạo một Hook useAuth tùy chỉnh

Để xác thực có thể tái sử dụng, chúng ta sẽ tạo một Hook useAuth quản lý đăng nhập, đăng xuất và trạng thái người dùng trên toàn cầu.

1. AuthProvider (Cung cấp ngữ cảnh)

import { useState, createContext } from "react"; export const AuthContext = createContext(null); export const AuthProvider = ({ children }) => { const [user, setUser] = useState(() => { const storedUser = localStorage.getItem("user"); return storedUser ? JSON.parse(storedUser) : null; }); const login = (username, role) => { const userData = { name: username, role }; setUser(userData); localStorage.setItem("user", JSON.stringify(userData)); }; const logout = () => { setUser(null); localStorage.removeItem("user"); }; return ( <AuthContext.Provider value={{ user, login, logout }}> {children} </AuthContext.Provider> );
};

2. Hook useAuth

import { useContext } from "react";
import { AuthContext } from "./AuthProvider"; export const useAuth = () => { const { user, login, logout } = useContext(AuthContext); const isAuthorized = (requiredRole) => { return user && user.role === requiredRole; }; return { user, login, logout, isAuthorized };

3. Thuận lợi

  • Có thể sử dụng trên nhiều component.
  • Cung cấp trạng thái xác thực tập trung.
  • Loại bỏ logic xác thực dư thừa.

Sử dụng useAuth trong một Component

Hãy cấu trúc lại thành phần xác thực của chúng ta để sử dụng Hook useAuth.

import React from "react";
import { useAuth } from "./useAuth"; const AuthComponent = () => { const { user, login, logout } = useAuth(); return ( <div> {user ? ( <> <h2>Welcome, {user.name}!</h2> <button onClick={logout}>Logout</button> </> ) : ( <button onClick={() => login("John Doe", "user")}>Login</button> )} </div> );
}; export default AuthComponent;

Bao bọc thành phần gốc bằng AuthProvider

Để xác thực khả dụng trên toàn bộ ứng dụng, hãy bọc thành phần gốc của bạn bằng AuthProvider.

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { AuthProvider } from "./AuthProvider";
import App from "./App"; const rootElement = document.getElementById("root");
const root = createRoot(rootElement); root.render( <StrictMode> <AuthProvider> <App /> </AuthProvider> </StrictMode>
);

Ví dụ: Bảo vệ các Admin Routes

import React from "react";
import { useAuth } from "./useAuth"; const AdminPanel = () => { const { user, isAuthorized } = useAuth(); if (!user || !isAuthorized("admin")) { return <h2>Access Denied</h2>; } return <h2>Welcome to the Admin Panel</h2>;
}; export default AdminPanel;

Ví dụ: Bảo vệ các Routes bằng thành phần bậc cao hơn (HOC)

import React from "react";
import { useAuth } from "./useAuth";
import { Navigate } from "react-router-dom"; const ProtectedRoute = ({ children, requiredRole }) => { const { user, isAuthorized } = useAuth(); if (!user || (requiredRole && !isAuthorized(requiredRole))) { return <Navigate to="/login" replace />; } return children;
}; export default ProtectedRoute;

Thuận lợi:

  • Đơn giản hóa việc kiểm soát truy cập dựa trên vai trò.
  • Tránh việc kiểm tra quyền hạn nhiều lần.
  • Dễ dàng bảo vệ các tuyến đường bằng một thành phần ProtectedRoute có thể tái sử dụng.

Hy vọng thông tin vừa rồi sẽ hữu ích đối với các bạn!

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tìm hiểu về Redux Thunk

Chào mọi người, nếu bạn là người đã biết về React và đang làm quen với Redux chắc hẳn bạn đang rất mơ hồ về các khái niệm cơ bản của Redux như dispatch, store, action creator,... bạn còn đang vật lộn với đống document của Redux để hiểu những khái niệm đó và bạn nghe ai đó trong team nói về Redux Thu

0 0 401

- vừa được xem lúc

[React] Giới thiệu tổng quát về Redux Toolkit

1. Redux Toolkit (RTK) là gì và tại sao lại có nó. . .

0 0 6.6k

- vừa được xem lúc

Uống Pepsi code Vue đi - Uống Cocacola code React nha ;)

. (Nguồn ảnh: Internet). Chào các bạn, chào các bạn. Let's go . 1.

0 0 149

- vừa được xem lúc

Cài đặt taillwind css cho dự án React

Trong bài viết cùng mình tìm hiểu cách cài đặt tailwind css cho một dự án React sẵn có. .

0 0 148

- vừa được xem lúc

Formik vs React Hook Form (Phần 1)

Các lập trình viên Front End đều làm việc rất nhiều với form cùng sự phức tạp của ứng dụng. Do vậy chúng ta cần những thư viện form mạnh mẽ hỗ trợ quản lý các form state, form validation... Thành phần module. Formik bao gồm có 9 dependencies khác. . React Hook Form thì không có.

0 0 373

- vừa được xem lúc

Hướng dẫn React Redux cho người mới bắt đầu - Phần 1

Lời mởi đầu. Chào các bạn, ở thời điểm thực hiện bài viết này mình cũng là một người đang bắt đầu tìm hiểu và học với ReactJs và Redux, trong quá trình tìm hiểu đọc các tài liệu về thư viện này mình có tìm được một bài hướng dẫn khá hay nên đã quyết định chia sẻ với mọi người .

0 0 283