핵심
✅ [토큰 전달방법]
- accessToken은 요청 header의 Authorization으로 보낸다.
- accessToken 쿠키 관리
- ⛔️ 쿠키관련 옵션 맞추는데 시간
- accessToken 로컬스토리지 관리 ✅
- ✅ 쿠키보다 관리 쉬움
- accessToken 전역 상태로만 관리
- ✅ 보안상 이점
- ⛔️ 새로고침 시 날라감, + refreshToken 로직 필요
✅ [유저 새로고침 시 & 페이지 이동 시 로그인 유지]
- AuthRoute에서, 페이지 이동 시 마다, 현재 Token을 검증하고, 유효하다면,
isAuth === true
로 변경하여 준다.
- url state로 진입 페이지 추적
✅ [인가- 로그인해야지만 들어갈 수 있는 페이지 관리]
PrivateRoute
- 로그인한다면 계속
- 로그인 하지 않는다면 Login 페이지로 redirect 하는 Route 생성
⛔️ [다른페이지에서 로그인 요청 시 redirect]
- PrivateRoute에서 로그인 요청한 path를 location.state에 담는다. ✅
- 혹은 특정 페이지에서 로그인 페이지 이동 시, 그 path를 state.from에 담아 넘긴다. ✅
- 로그인페이지로 이동하면, location.state.from의 값을 확인한다. ✅
- useUserAction.login 에서, 로그인 성공 후, location.state에 담긴 path로 redirect 시켜준다.
[토큰 만료 시]
- accessToken이 만료된 경우, axiosInstance의 intercepter의 response 부분에서 catch 하여, 새로운 accessToken을 발급 받아 작업을 수행하도록 한다.
테스트 시나리오
[성공 시나리오]
- 로그인 > 📌 kakao Id, PW 입력창 확인> token발급 >
isNew === true
- 📌 /register 페이지 이동 확인
isNew === false
- 📌 메인 페이지 이동 확인
[로그인 유지 테스트]
- 로그인 > token 발급 후 localStorage 저장
- 📌 localStorage 저장 확인
- 페이지 이동 시, AuthRoute에서 authCheck 요청
[header에 token 전송 테스트]
- 📌 로그인 후 요청 시 header에 token 전송 확인
[인가 테스트]
- 📌 로그인 안했을 경우 포스트 페이지 접근 불가 확인
- 📌 로그인 했을 경우 포스트 페이지 접근 확인
[redirect 테스트]
- 📌 로그인 하지 않고, Home에서 포스트 페이지 접속 시도 > 로그인 페이지 redirect > 로그인 성공 후 포스트페이지로 redirect
- ⛔️ 메인페이지 redirect
- 카카오 외부링크를 거치면서, 가지고 있던 location을 잃는 것으로 추정
작업순서
전역recoil store 생성 ⇒ cookie 관련 module 생성 ⇒ login, logout, authUser api 로직 작성 ⇒ 관련 후 인증 관련 상태 처리 로직 작성 ⇒ authRoute 통한 새로고침, 토큰 만료 대응 ⇒ authRoute 인가 관련 기능 추가
- recoil store 생성 (link)
- 전역상태 관리
- 현재 로그인한 userData
- 현재 token
- 현재 로그인 여부
- 로그인 시
- user 등록
- accesstoken 등록
- 현재 로그인 여부 update
- 새로고침 시, 토큰 만료 시
- 1) 모든 Route 진입 시, authUser()를 실행
- 2) authUser() 에서는 localStorage의 token을 통해 user정보를 가져와 업데이트 함
- token이 만료되어 user 정보가 없다면, 모든 정보를 지우고 로그아웃 처리함
code
function AuthRoute({ mode, ...props }: Props) { const { authUser } = useAuthContext(); const [loading, setLoading] = useState(true); useEffect(() => { (async () => { console.log('here'); await authUser(); setLoading(false); })(); }, [authUser]); if (loading) return null; return mode === 'private' ? ( <PrivateRoute {...props} /> ) : ( <Route {...props} /> ); } export default AuthRoute;
code
const authUser = useCallback(async () => { try { const authedUser = await auth.getAuthUser(token); setUser(authedUser); setIsAuth(true); } catch (error) { removeUser(); removeToken(); setIsAuth(false); } }, [token, setUser, removeUser, removeToken]);
관심사 분리와 하나의 책임에 신경써서 구현
api는 해당 api 요청만 처리하도록
useUserActions 는 api이후, 전역상태 처리를 위해 사용
실제 화면단에서는 useUserActions를 통해 인증관련 로직 처리