💡 로그인에 성공했으니, 이번엔 새로고침을 해도 로그인이 유지되는 기능을 구현해보자.
지난 글에 작성해둔 로그인 과정을 다시 한 번 살펴보자.
아래 로직에 몇 가지 작업을 추가해 로그인 유지 기능을 만들어 볼 것이다.
❶ 유저가 앱에 접속
👉 index.tsx의 useCheckToken이 실행된다.
const useCheckToken = () => {
const token = useToken();
const setToken = useSetToken();
const router = useRouter();
useEffect(() => {
if (token) {
isTokenValid(token).then((isValid) => {
if (!isValid) {
setToken(null);
router.push("/login");
}
});
} else {
router.push("/login");
}
}, [router, setToken, token]);
};
useToken에 토큰 있으면 isTokenValid 로 토큰의 유효성을 검사한다.
유효하지 않다면 로그인 페이지로 리다이렉트
유효하다면 메인 페이지로 이동
useToken에 토큰 없으면 바로 로그인 페이지로 리다이렉트 한다.
❷ login.tsx
로그인 버튼이 있는 페이지. 유저가 버튼을 클릭하면 requestLogin
API를 호출한다.
❸ loading.tsx
Spotify App에 등록해놓은 Redirect URL이다.
스포티파이 로그인 페이지에서 유저가 스포티파이로 로그인 하면 해당 페이지로 리다이렉트 된다.
해당 페이지의 useEffect에서 query string을 파싱하고, getToken
API를 호출한다.
getToken
의 응답으로 받은 access_token을 useSetToken을 활용해 저장한다.
로컬스토리지를 이용해 구현할 것이다.
구체적으로 두 가지 작업이 필요하다.
각 작업을 어느 시점에 할 지 결정하면 된다.
로컬스토리지에 토큰을 저장하는 작업은, 서버로부터 토큰을 새로 받아올 때 하면 된다!(❸번에 추가)
로컬스토리지로부터 토큰을 읽어오는 작업은 새로고침 시에 매번 수행되는 useCheckToken(❶번 과정)에 추가하면 될 것 같다. useCheckToken 내 useEffect에, 로컬스토리지로부터 토큰을 읽어와 useSetToken으로 저장하는 로직을 추가한다.
이렇게 수정한다.
const useCheckToken = () => {
const token = useToken();
const setToken = useSetToken();
const router = useRouter();
useEffect(() => {
/* 추가한 코드
if (localStorage.getItem("access_token") !== null) {
setToken(JSON.parse(localStorage.getItem("access_token")));
}
*/
if (token) {
isTokenValid(token).then((isValid) => {
if (!isValid) {
setToken(null);
router.push("/login");
} else {
router.push("/");
}
});
} else {
router.push("/login");
}
}, [router, setToken, token]);
};
구현 완료!
새로운 문제점을 발견했다.
새로고침을 하지 않은 채로 1시간이 경과했다고 가정하자.
이 상황에서 유저가 플레이 버튼을 누른다면?
토큰이 expired 상태이기 때문에 플레이가 되지 않는다.
물론 새로고침을 하면 해결되겠지만, 이는 유저에게 불편함을 준다.
또 다음 글에서 해결해보도록 하자!!!!
리팩토링 재밌당.