보통 페이지를 만들 때 로그인을 해야만 접근할 수 있는 페이지와 그렇지 않은 페이지가 나뉜다.
보통은 로그인 여부를 체크해서 필요한 페이지, 접근경로만 보여 주었지만 URL 입력을 통해 언제든 접근할 수 있는 부분에 대해서 고민이 되었다.
각 페이지마다 체크하거나, 재사용 가능한 모듈을 만들거나의 방법도 있는데, 아예 Router에서 로그인 인증 / 접근 제한을 설정하는 방법이 있다고 하여 프로젝트에 적용해 보기로 했다.
import styled from 'styled-components';
import AutoRouter from './router/AutoRouter';
const App = () => {
return (
<>
<GlobalStyle />
<AutoRouter />
</>
);
};
export default App;
Router를 App컴포넌트에서 분리해 AutoRouter 파일에서 설정하고 있어서, 해당 파일을 수정해 구현했다.
경로(path
), 렌더링할 컴포넌트(element
), 그리고 사용자 인증이 필요한지 여부를 나타내는 속성(withAuthorization
)으로 이뤄진 라우팅에 필요한 경로 정보(RouterInfo)를 배열로 정의해 두었다.
import {
BrowserRouter as Router,
Routes,
Route,
Navigate,
} from 'react-router-dom';
// ...
type RouterItem = {
path: string;
element: JSX.Element;
withAuthorization: boolean;
};
const RouterInfo: RouterItem[] = [
{ path: '/', element: <Home />, withAuthorization: false },
{ path: '/account/login', element: <Login />, withAuthorization: false },
{ path: '/account/signup', element: <Signup />, withAuthorization: false },
{ path: '/my/page', element: <Login />, withAuthorization: true },
{ path: '/my/seller_center', element: <Signup />, withAuthorization: true },
{ path: '/my/cart', element: <Cart />, withAuthorization: true },
{
path: '/products/:id',
element: <ProductDetail />,
withAuthorization: false,
},
];
withAuthorization
- 로그인 된 상태에서 접근할 수 있는 페이지는 true
, 로그인 상관 없이 접근 가능한 페이지는 false
로 설정로그인 인증을 확인하고 처리하기 위한 컴포넌트(Authorization)를 만든다.
로그인이 되었는지 아닌지의 상태를 확인하기 위해 로그인 시 localstorage.setItem
로 로컬스토리지에 저장했던 token
값을 이용했다.
interface AuthorizationProps {
redirectTo: string;
children: React.ReactNode;
}
const isAuthenticated: string | null = localStorage.getItem('token');
const Authorization = ({
redirectTo,
children,
}: AuthorizationProps) => {
if (isAuthenticated) {
return <>{children}</>;
} else {
return <Navigate to={redirectTo} />;
}
};
token
을 가져와 isAuthenticated
에 담는다.마지막으로, 위에서 정의한 경로 정보와 인증 컴포넌트를 이용해 렌더링한다.
RouterInfo에서 설정한 속성 withAuthorization
이 false인 페이지는 그대로 렌더링하고, withAuthorization
이 true인 페이지는 Authorization 컴포넌트를 통해 인증을 거쳐 인증에 실패하면 로그인 페이지 경로/account/login
로 이동하도록 설정하였다.
const AutoRouter = () => {
return (
<Router>
<Routes>
{RouterInfo.map((route) => {
return (
<Route
key={route.path}
path={route.path}
element={
route.withAuthorization ? (
<Authorization
isAuthenticated={isAuthenticated}
redirectTo='/account/login'
>
{route.element}
</Authorization>
) : (
route.element
)
}
/>
);
})}
</Routes>
</Router>
);
};
export default AutoRouter;
하나 물어봐도 될까요? 토큰을 가져올때 RefreshToken인가요? AccessToken인가요?