[React] react-router-dom을 사용하여 로그인 유무에 따라 사용자 접근 막기

apro_xo·2022년 10월 17일
1
post-thumbnail

주소창을 통한 페이지 이동 막기

웹 어플리케이션을 개발하다 보면 사용자의 권한에 따라 페이지의 접근을 막아야하는 경우가 자주 발생한다.

예를 들면, 로그인을 하지 않은 사용자가 방문하면 안 되는 페이지가 있을 수 있다. 페이지를 이동하는 네비게이션 바의 버튼을 클릭 시 항상 로그인 유무를 파악하여 접근을 막을 수 있다.

하지만 이는 사용자가 주소창을 통해 개발자의 의도와 다르게 비정상적으로 접근하는 경우를 막을 수 없다.

이를 해결하기 위해 페이지 컴포넌트에서 useEffect를 사용하여 로그인 유무를 판단하고, 로그인이 되지 않았다면 페이지를 나가도록 구현하는 등을 생각할 수 있지만 이 방법의 단점은 페이지를 일단 무조건 한 번 들어간다는 것이다.

예를 들어, 페이지 이동이 완료 된 후 사용자의 로그인 유무를 판단하여 로그인 페이지로 이동하게 하거나, alert를 띄워 사용자에게 로그인을 권유한다는 것이다.

이는 사용자 경험을 저해할 수 있고, 각 컴포넌트마다 useEffect에 로그인을 판단하는 로직을 구현해야한다. 매우 비효율적이고 별로 좋지 않은 방법이라는 것을 알 수 있다.

따라서 react-router-dom을 사용하여 이를 막는 방법을 사용해보았다.

PrivateRoute 생성 및 사용

// app.js
function App() {

const context = useContext(userContext);
  const location = useLocation();
  const access = context.state.userInfo.username;
  const { setUserInfo } = context.actions;
  const token = sessionStorage.getItem("Authorization");
  
  ...(생략)
  
  return (
    <ThemeProvider theme={theme}>
    <div className="App">
        <GlobalStyle/>
        <Helmet>
          ...(생략)
        </Helmet>
        <Content>
        <AnimatePresence exitBeforeEnter>
          ...(생략)
            <Route path="/viewer/room" element={<PrivateRoute component={<RoomViewer/>} authenticated={token}/>}/>
            <Route path="/viewer/room/search/:hashtag" element={<PrivateRoute component={<RoomViewer/>} authenticated={token}/>}/>
            <Route path="/detail/posting/:postingId" element={<PrivateRoute component={<Detail />} authenticated={token}/>} />
            <Route path="/signup" element={<Signup />}></Route>
          ...(생략)
// PrivateRoute.jsx
import React from 'react';
import { Navigate } from 'react-router-dom';

const PrivateRoute = ({ authenticated, component:Component}) => {

    return(
        authenticated?Component:<Navigate to="/login" {...alert("로그인이 필요합니다.")}></Navigate>
    )
}

export default PrivateRoute;

위의 코드들은 실제로 내가 프로젝트간 사용했던 코드다.

먼저 PrivateRoute.jsx를 설명하면, props로 사용자의 로그인 유무를 파악할 수 있는 authenticated 와 로그인이 되어있는 상태라면 렌더링 할 컴포넌트 component를 받아온다.

그리고 authenticated가 참이라면 Component를 return하고, 거짓이라면 react-router-dom의 Navigate를 사용하여 로그인 페이지로 리다이렉트 하고, alert를 통해 사용자에게 로그인이 필요하다는 경고창을 띄워준다.

app.js를 보면,

<Route path="/viewer/room" element={<PrivateRoute component={<RoomViewer/>} authenticated={token}/>}/>

위와 같이 PrivateRoute를 사용하는데, /viewer/room으로 라우팅이 되었을 때 PrivateRoute 컴포넌트로 먼저 들어가고, 사용자의 로그인 유무를 파악할 수 있는 값인 token을 props로 넘겨주어 로그인 유무를 파악하고, 이에 따라 컴포넌트를 렌더링 하도록 만들 수 있다.

profile
유능한 프론트엔드 개발자가 되고픈 사람😀

0개의 댓글