본문으로 바로가기

HOC을 통한 인증 미들웨어

category React, Next, Redux/⚛ React.JS 2020. 5. 30. 02:47

로그인한 회원만 진입 가능한 페이지 관리자만 진입 가능한 페이지 등을 구별해야 한다. 


페이지 외에도 댓글 작성, 파일 전송/업로드에도 마찬가지이다. node에서는 간단히 미들웨어로 구현할 수 있었지만 React에서는 특정 컴포넌트에 접근하기 전 인증을 체크해서 인증을 통과하지 않으면 아예 렌더를 안하게끔 만들어야 한다.

React에서는 HOC를 통해 특정 컴포넌트를 감싼 후 HOC의 단계에서 백단으로 axios을 날려서 해당 유저가 로그인된 상태인지 아닌지를 체크하고 특정 컴포넌트로 접속하게 만들거나 강제로 다른 곳을 리다이렉트 해주면 됩니다.


 

hoc을 하나 만들어줬습니다. redux는 너무 번잡해서 생략했습니다. 구조만 봅시다.

입력받은 조건을 모두 통과했다면 입력한 컴포넌트를 return하는 것을 잊지 맙시다.

import React, { useEffect } from "react";
import { useDispatch } from "react-redux";
import { auth } from "../_actions/user_action";

export default function (SpecificComponent, option, adminRoute = null) {
  // option: null => 아무나 출입 가능
  // option: true => 로그인 유저만
  // option: false => 로그인 하면 출입 불가능한 곳(회원가입 등...)

  function AuthenticationCheck(props) {
    const dispatch = useDispatch();
    useEffect(() => {
      dispatch(auth()).then((res) => {
        if (!res.payload.isAuth) {
          if (option === true) {
            props.history.push("/login");
          }
        } else {
          if (adminRoute && !res.payload.isAdmin) {
            props.history.push("/");
          } else {
            if (option === false) {
              props.history.push("/");
            }
          }
        }
      });
    }, []);
    return <SpecificComponent />;
  }
  return AuthenticationCheck;
}

 

 

react-router-dom으로 router 처리를 한 곳을 HOC인 Auth로 감싸주었다.

 

import React, { Fragment } from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import LandingPage from "./components/views/LandingPage/LandingPage";
import LoginPage from "./components/views/LoginPage/LoginPage";
import RegisterPage from "./components/views/RegisterPage/RegisterPage";
import Auth from "./hoc/auth";

function App() {
  return (
    <Fragment>
      <Router>
        <Route path="/" exact component={Auth(LandingPage, null)}></Route>
        <Route path="/login" exact component={Auth(LoginPage, false)}></Route>
        <Route path="/register" exact component={Auth(RegisterPage, false)}></Route>
      </Router>
    </Fragment>
  );
}

 

 

 

이번 프로젝트에서는 이런 식으로 짰다.

function withAuthHoc(WrappedComponents) {
  const AuthenticationCheck = (props) => {
    useEffect(() => {
      axios.post("/auth/jwtauthcheck").then((res) => {
        console.log(res.data);
        if (!res.data.isAuth) return props.history.push("/");
      });
    }, []);
    return <WrappedComponents />;
  };
  return AuthenticationCheck;
}

export default withAuthHoc;

darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체