본문 바로가기
React

boilerplate(client) - Authentication 기능 만들기

by _sweep 2021. 6. 22.

따라하며 배우는 노드, 리액트 기본 강의를 듣고 정리한 내용입니다.

 

 

 

 

Authentication 기능을 위한 Redux 설정하기

1. type 설정

src > action 폴더의 type.js에 Auth 기능을 위한 type을 설정한다.

 

export const AUTH_USER = "auth_user";

 

 

2. auth action 구현

src > action 폴더의 user_action.js에 auth를 위한 요청을 서버에 보내는 작업을 구현한다.

 

import axios from 'axios';
import {
    AUTH_USER
} from './types';

export function auth() {

    const request = axios.get('/api/users/auth')
    .then(response => response.data);

    return {
        type: AUTH_USER,
        payload: request
    }
} 

 

axios.get()을 이용하여 서버에서 받은 data를 request에 저장한다.

이후 action의 타입과 request를 return 시킨다.

 

 

3. auth reducer 구현

src > reducer 폴더의 user_reducer.js에 auth reducer를 구현한다.

 

import {
    LOGIN_USER,
    REGISTER_USER,
    AUTH_USER
} from '../_actions/types';

export default function(state={}, action) {
   switch (action.type) {
        case LOGIN_USER:
            return {...state, loginSuccess: action.payload}
            
        case REGISTER_USER:
            return {...state, register: action.payload}
            
        case AUTH_USER:
            return {...state, userData: action.payload}
            
        default:
            return state
    }
}

 

앞선 기능 구현때와 마찬가지로 각 action의 타입에 따라 서버로부터 받은 내용을 userData에 저장 후 state와 함께 return한다.

서버 구현 시 요청에대한 응답으로 user 정보들을 보내도록 했기 때문에 userData에는 user에 대한 정보들이 담길 것이다.

 

 

Authentication 기능 구현하기

1. auth.js 구현

hoc 폴더 생성 후 그 안에 auth.js 파일을 생성한다.

 

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

export default function(SpecificComponent, option, adminRoute = null) {

    function AuthenticationCheck(props) {

        const dispatch = useDispatch();

        useEffect(() => {
            dispatch(auth()).then(response => {
                
                // 로그인 하지 않은 상태
                if(!response.payload.isAuth) {
                    if(option){
                        alert("로그인 후 이용 가능한 페이지입니다.");
                        props.history.push('/login');
                    }
                }
                else { // 로그인한 상태
                    if(adminRoute && !response.payload.isAdmin){
                        alert("관리자만 사용 가능한 페이지입니다.");
                        props.history.push('/');
                    }
                    else{
                        if(option === false){
                            props.history.push('/');
                        }
                    }
                }
            });
        }, []);

        return (
            <SpecificComponent />
        );
    }

    return AuthenticationCheck;
}

 

인자로 component와 option, adminRoute를 받는다.

 

option은 다음과 같다.

  • option = null : 아무나 출입 가능
  • option = true : 로그인한 유저만 출입 가능
  • option = false : 로그인한 유저는 출입 불가

adminRoute는 true일 경우 admin user만 출입 가능하다.

하지만 boilerplate에서는 admin user를 따로 지정하지 않았기에 null을 준다.

 

구현하고자 하는 내용은 다음과 같다.

  • 로그인하지 않은 상태로 로그인 후 이용가능한(option = true) 페이지에 접근할 경우 : 안내 메세지를 출력하고 LoginPage로 이동시킨다.
  • 로그인한 상태로 관리자만 이용가능한 페이지에 접근할 경우 : 안내 메세지를 출력하고 LandingPage로 이동시킨다.
  • 로그인한 상태로 로그인한 유저는 출입 불가한 페이지에 접근할 경우 (ex. 회원가입페이지, 로그인페이지) : 별도의 안내 메세지 없이 LandingPage로 이동시킨다.

이와 같은 action을 dispatch를 통해 전달시켰다.

 

 

2. App.js에 auth 기능 적용

위와 같이 구현한 auth 기능을 적용하기 위해 app.js를 수정한다.

 

import React from 'react';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} 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 (
    <Router>
    <div>
      {/*
        A <Switch> looks through all its children <Route>
        elements and renders the first one whose path
        matches the current URL. Use a <Switch> any time
        you have multiple routes, but you want only one
        of them to render at a time
      */}
      <Switch>
        <Route exact path="/" component={Auth(LandingPage, null)} />
        <Route exact path="/login" component={Auth(LoginPage, false)} />
        <Route exact path="/register" component={Auth(RegisterPage, false)} />
      </Switch>
    </div>
  </Router>
  );
}

export default App

 

위와같이 Route의 component에 Auth()를 추가한 후 component와 option값을 인자로 넘겨주면 된다.

 

LangingPage의 경우 아무나 출입이 가능하므로 option에 null을 넣어주었다.

LoginPage와 RegisterPage의 경우 login한 유저는 출입이 불가한 페이지이므로 option에 false를 넣어주었다.

 

 

3. 각 Page.js 수정

위의 상태에서 프로그램을 실행시키면 오류가 발생한다.

 

이를 해결하기 위해서 각 Page.js에 해당 내용을 추가한다.

 

// RegisterPage.js 수정 예시

import { withRouter } from 'react-router-dom';

// export default RegisterPage;를 아래와 같이 수정
export default withRouter(RegisterPage);

 

 

결과

결과 확인을 위해 임의로 로그인한 유저가 로그인한 유저는 출입이 불가한 페이지에 접근할 때 안내메세지를 띄우도록 하였다.

 

 

로그인을 한 후 LoginPage에 접근하려 했을 때 다음과 같은 안내 메세지를 확인할 수 있었고 안내 메세지의 확인 버튼을 누르자 LandingPage로 돌아가는 것까지 확인하였다.

 

 

댓글