Context API 및 React 쿠키를 사용하여 React에서 토큰으로 경로를 보호하는 방법

어떻게 될까요?



react-router-dom v6에서 JWT 인증으로 경로를 보호하는 방법을 배웁니다. 경로는 사용자가 쿠키(또는 로컬 저장소)에 저장된 토큰을 가지고 있는 경우에만 액세스할 수 있습니다.

중고 기술



  • 반응 ^18.2.0;

  • JWT;

  • 악시오스 ^0.27.2;

  • react-router-dom ^6.3.0;

  • 반응 쿠키 ^4.1.1;

  • 시작



    React 앱을 만들어 봅시다

    create-react-app protect-route-with-jwt
    


    이 명령은 필요한 파일과 함께 반응 프로젝트 구조를 생성합니다. 일부 파일을 제거하고 프로젝트에서 사용할 일부 폴더를 만듭니다. 최종 구조는 다음과 같습니다.


    이제 몇 가지 프로젝트 종속성을 설치하고 프로젝트 폴더 내부의 터미널을 열고 다음 명령을 실행합니다.

    yarn init
    yarn add axios react-router-dom react-cookie
    


    API 정의


    src > services > api.js에 파일을 생성하여 애플리케이션에서 요청을 만들기 위해 baseURL을 정의합니다.

    import axios from 'axios';
    
    const api = axios.create({
        baseURL: "http://localhost:8000" //your api URL
    });
    
    export default api;
    


    src > services > api.js



    우리는 axios 라이브러리에서 API 변수를 정의하고 내보내고 있습니다.

    후크 만들기


    src > hooks로 이동하여 authprotect Routes라는 두 개의 폴더를 만듭니다. 그 안에 hooks 폴더가 index.js 파일을 생성합니다.

    인증



    import { createContext, useContext, useMemo } from 'react';
    import { useCookies } from 'react-cookie';
    import { useNavigate } from 'react-router-dom';
    import api from '../../services/api';
    
    const UserContext = createContext();
    
    export const UserProvider = ({ children }) => {
        const navigate = useNavigate();
        const [cookies, setCookies, removeCookie] = useCookies();
    
        const login = async ({ email, password }) => {
            const res = await api.post('/auth', {
                email: email,
                password: password
            });
    
            setCookies('token', res.data.token); // your token
            setCookies('name', res.data.name); // optional data
    
            navigate('/home');
        };
    
        const logout = () => {
            ['token', 'name'].forEach(obj => removeCookie(obj)); // remove data save in cookies
            navigate('/login');
        };
    
        const value = useMemo(
            () => ({
                cookies,
                login,
                logout
            }),
            [cookies]
        );
    
        return (
            <UserContext.Provider value={value}>
                {children}
            </UserContext.Provider>
        )
    };
    
    export const useAuth = () => {
        return useContext(UserContext)
    };
    

    src > hooks > auth > index.js



    기본적으로 여기서는 로그인 및 로그아웃 기능이 있는 사용자 컨텍스트를 생성하고 모든 수준에서 수동으로 소품을 전달하지 않고도 구성 요소 트리를 통해 사용할 수 있도록 내보냅니다. 이해가 되지 않으면 contextAPI 설명서를 참조하십시오.

    보호 경로



    import { Outlet, Navigate } from 'react-router-dom';
    import { useAuth } from '../auth';
    
    export const ProtectRoutes = () => {
        const { cookies } = useAuth();
    
        return cookies.token ? <Outlet/> : <Navigate to='/login' exact />
    };
    

    src > hooks > protectRoutes > index.js



    여기에서 이전에 정의한 useAuth를 사용하여 경로 보호를 생성하고 있습니다. 쿠키에 토큰이 있으면 애플리케이션을 따르고 그렇지 않으면 로그인 페이지로 리디렉션합니다.

    후크



    응용 프로그램에서 사용할 모든 공급자를 추가하는 후크의 공급자 인덱스를 만듭니다. 이 경우 애플리케이션의 전역 컨텍스트에서 사용될 인증 후크만 가져오기 및 추가하기만 하면 됩니다.

    import { UserProvider } from './auth';
    
    const AppProvider = ({ children }) => (
        <>
            <UserProvider>{ children }</UserProvider>
        </>
    );
    
    export default AppProvider;
    


    src > hooks > index.js



    이제 AppProvider 안에 넣은 모든 것이 useAuth 후크에 액세스할 수 있습니다.

    페이지 만들기



    이 예제에 대해 홈 페이지와 로그인 페이지의 두 페이지를 만듭니다. src > pages에 위치합니다.

    예제 페이지는 다음과 같습니다.

    import React from 'react';
    
    export default function Home() {
        return <div>Home Page</div>
    }
    
    


    src > pages > Home > index.js



    import React, { useState } from 'react';
    import { useAuth } from "../../hooks/auth";
    
    export default function Login() {
        const [cnpj, setCnpj] = useState('');
        const [password, setPassword] = useState('');
        const { login } = useAuth();
    
        const handleLogin = () => {
            login({ cnpj, password });
        }
    
        return (
            <div>
                <input onChange={e => setCnpj(e.target.value)} placeholder="Email"/>
                <input onChange={e => setPassword(e.target.value)} placeholder="Password"/>
                <button onClick={handleLogin} type="submit">Login</button>
            </div>
        )
    }
    


    src > pages > Login > index.js



    경로 생성



    src 폴더의 index.js로 이동하여 다음 코드를 추가합니다.

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import { BrowserRouter } from 'react-router-dom';
    import AppProvider from './hooks';
    import App from './App';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <React.StrictMode>
        <BrowserRouter>
          <AppProvider>
            <App />
          </AppProvider>
        </BrowserRouter>
      </React.StrictMode>
    );
    


    src > index.js



    일부 애플리케이션 경로를 정의하고 마지막으로 이를 보호해 보겠습니다. App.js로 이동하여 다음 코드를 추가합니다.

    import React from 'react';
    import { Route, Routes, Navigate } from 'react-router-dom';
    import { ProtectRoutes } from './hooks/protectRoutes';
    import Home from './pages/Home';
    import Login from './pages/Login';
    
    export default function App() {
      return (
        <Routes>
          <Route path='/' element={ <Navigate to='home' exact /> } />
          <Route path='/login' element={ <Login /> } />
    
          <Route element={ <ProtectRoutes /> }>
            <Route path='/home' element={ <Home /> } />
          </Route>
        </Routes>
      )
    }
    


    src > App.js



    여기서는 Routes 구성 요소 내부에 경로를 정의합니다. 보호하려는 경로 주변에 보호된 경로를 추가하려면 <Route>를 요소로 사용하여 ProtectRoutes 태그를 충분히 엽니다. 태그 내부에 경로를 추가할 것입니다. 이 경우 홈 경로를 보호합니다. 즉, 사용자는 보호에서 정의한 쿠키에 토큰이 있는 경우에만 액세스할 수 있습니다. 이전 경로.

    즉, 이제 사용자 인증으로 보호해야 하는 모든 경로는 <ProtectRoutes> 요소가 있는 경로에 배치되어야 합니다.

    내 github에서 이 프로젝트에 액세스할 수 있습니다: https://github.com/ViniBGoulart/protect-route-with-jwt

    좋은 웹페이지 즐겨찾기