본문 바로가기
Web/React Node js

리액트 기초 강의 (12) - 인증체크

by SeleniumBindingProtein 2022. 3. 2.
728x90
반응형

1. 회원이 접근할 수 있는 페이지는 권한이나 상태에 따라 다를 수 있고, 이러한 페이지에 대한 통제는 HOC를 이용함

   HOC : 다른 컴포넌트를 받아 새로운 컴포넌트를 return하는 function 

   - 아래와 같이 상태를 체크하여 페이지를 통제하는 방식임

import React from 'react';
import {
  BrowserRouter as Router,
  Routes,
  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() {
  const NewLandingPage = Auth(LandingPage, null);
  const NewLoginPage = Auth(LoginPage, false);
  const NewRegisterPage = Auth(RegisterPage, false);

  return (
    <Router>
      <Routes>
        <Route path="/" element={<NewLandingPage/>} />
        <Route path="/login" element={<NewLoginPage/>} />
        <Route path="/register" element={<NewRegisterPage/>} /> 
      </Routes>
  </Router>
  );
}

export default App;

   - hoc 디렉토리에 auth.js 생성

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

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

    //null => 아무나 출입이 가능한 페이지
    //true => 로그인한 유저만 출입이 가능한 페이지
    //false => 로그인한 유저는 출입 불가능한 페이지
    function AuthenticationCheck(props){
        const dispatch = useDispatch();
        const navigate = useNavigate();
        
        //auth에서 option과 adminRoute를 체크하여 올바르지 않은 접근을 제어하는 것
        useEffect(() => {
            dispatch(auth()).then(response =>{
                console.log(response)

                //로그인 하지 않은 상태
                if(!response.payload.isAuth){
                    if(option){
                        navigate('/login')
                    }
                }else{
                //로그인 한 상태
                    if(adminRoute && !response.payload.isAdmin) {
                        navigate('/')
                    } else {
                        if(option === false)
                            navigate('/')
                    }
                }
            })
           
        }, [])

        return(
            <SpecificComponent{...props}/>
        )
    }
    return AuthenticationCheck
}

- AuthenticationCheck 함수는 현재 브라우저의 상태를 가져오는 함수이고,

   redux를 이용할 것이기 때문에 dispatch를 이용하여 action을 보내야 함

    action 이름은 auth라 지정했고 action을 작성함

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

export function loginUser(dataTosubmit){
    const request = axios.post('/api/users/login', dataTosubmit)
        .then(response => response.data)
    
    return {
        type: "LOGIN_USER",
        payload: request
    }
}

export function registerUser(dataTosubmit){
    const request = axios.post('/api/users/register', dataTosubmit)
        .then(response => response.data)
    
    return {
        type: "REGISTER_USER",
        payload: request
    }
}


export function auth(){
    const request = axios.get('/api/users/auth')
        .then(response => response.data)
    
    return {
        type: "AUTH_USER",
        payload: request
    }
}

- get 메서드를 사용하는 auth action이고, 관련된 type을 typs.js에 작성해야 하며, reducer를 수정하면 됨

export const LOGIN_USER = "login_user";
export const REGISTER_USER = "register_user";
export const AUTH_USER = 'auth_user'

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}
            break;
        case REGISTER_USER:
            return{...state, register: action.payload}
            break;
        case AUTH_USER:
            return{...state, userData: action.payload}
            break;
        default:
            return state;
    }
}

[로그아웃]

[로그인]

728x90
반응형

댓글