인증 체크하기
회원이 접근할 수 있는 페이지는 권한이나 상태에 따라 다를 수 있다.
이러한 페이지에 대한 통제는 HOC를 이용한다.
HOC란 다른 컴포넌트를 받아 새로운 컴포넌트를 return 하는 fuction이다.
위와 같이 상태를 check해 페이지를 통제하는 방식이다.
hoc디렉터리에 auth.js라는 파일을 만들자.
import { response } from 'express';
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 => {
console.log(response)
})
}, [])
return(
<SpecificComponent />
)
}
return AuthenticationCheck
}
위와 같은 기본구조를 만들자.
AuthenticationCheck 함수는 현재 브라우저의 상태를 가져오는 함수이다.
redux를 이용할 것이기 때문에 dispatch를 이용하여 action을 보내야 한다. action 이름은 auth라 지정했고 action을 작성하자.
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를 수정하면 된다.
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}
case AUTH_USER:
return { ...state, userData: action.payload}
default:
return state;
}
}
response에 userData가 return 되기 때문에 return 값을 위와 같이 지정한다.
이제 작성한 hoc에 다른 컴포넌트들을 넣어주면 된다.
해당 부분은 App.js에서 적요하는데 개념과 비슷하게 Auth 컴포넌트로 다른 컴포넌트를 감싸면 된다.
이때 몇가지 옵션을 넣어서 적용할 수 있다.
- null: 아무나 출입이 가능
- true: 로그인한 유저만 출입이 가능
- false: 로그인한 유저는 출입 불가능
또한 adminRoute에 대한 옵션도 존재한다. defualt는 null이다.
이제 테스트를 해보자.
(props.history.push를 사용하려면 react-router-dom을 사용해야 하는데 이를 import하지 않으면 error가 발생할 수 있다.)
로그인을 하지 않아 payload에 Auth가 되지 않은 상태이다.
인증이 성공하고 서버에서 넘어온 userData를 확인할 수 있다.
다시 인증이 false가 되면서 로그아웃이 잘 되는 것을 확인할 수 있다.
이제 auth 컴포넌트에서 분기처리만 해주면 된다.
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 => {
// console.log(response)
//로그인 하지 않은 상태
if(!response.payload.isAuth){
if(option){
props.history.push('/login')
}
}else{
//로그인
//관리자 권한 체크
if(adminRoute && !response.payload.isAdmin){
props.history.push('/')
}else{
//로그인 유저가 접근 불가능한 페이지
if(option === false){
props.history.push('/')
}
}
}
})
}, [])
return(
<SpecificComponent />
)
}
return AuthenticationCheck
}
auth에서 option과 adminRoute를 체크하여 올바르지 않은 접근을 제어하는 것이다.
간단하게 하나만 테스트해보자.
만약 로그인한 유저가 로그인 페이지에 접근하려 해보자.
올바르게 동작한다면 LandingPage로 보내져야 한다.
<로그인 전> | <로그인 후> |
여기서 url을 login으로 옮겨보자.
다음과 같이 다시 LadingPage로 옮겨진다.
올바르게 동작하고 있다.