우리 로그인 로직은 accessToken
을 헤더에 담는 건데 새로고침을 하면 초기화 되기 때문에 다시 발급해줘야하는 상황이 발생한다.
그래서 사용한 것이 refreshToken
이다.
또 다른 이유는 accessToken
을 탈취 당했을때 다시 발급받기 위함과 유효기간을 연장시키기 위함이다.
accessToken
은 탈취 당하면 재발급 하면 그만이지만 refreshToken
을 탈취 당하면 보안에 크게 취약해 지기 때문에 서버에서 httpOnly : true 설정을 해줘서 클라이언트가 cookie를 사용하지 못하게 설정해 주었다.
💡 테스트 하다보니 response는 오는데 cookie는 안오는 상황이 생겨서 삽질을 좀 했는데 백과 프론트에서 withCredentials
설정을 true로 설정해주니까 해결되었다.
service/user.ts
export const mutateRefreshing = () => {
const url = '/api/user-service/refresh';
return axios.post<IResponseAuthToken>(url).then((res) => {
return res.data;
});
};
새로고침 할때마다 api 호출을 해서 refreshToken
도 재발급 받고 accessToken
도 재발급 받아서 바로 헤더에 담아주었다.
hook/use-mutate-refreshing.ts
export const useMutateRefreshing = (
mutateFunction: () => Promise<IResponseAuthToken>
) => {
const navigate = useNavigate();
const { mutate, data } = useMutation('refreshing', mutateFunction, {
onSuccess: (data) => {
axios.defaults.headers.common['Authorization'] =
'Bearer ' + data.accessToken;
},
onError: () => {
axios.defaults.headers.common['Authorization'] = '';
navigate({
pathname: '/signin',
});
},
});
return { mutate, data };
};
hook으로 빼준뒤에 성공시에 accessToken
을 헤더에 바로 담아주었다.
실패했을때는 유효하지 않다는 뜻이기 때문에 헤더를 비워주고 바로 로그인 페이지로 가도록 useNavigate
를 사용했다.
useEffect(() => {
refreshingHandler();
}, []);
그리고 홈페이지 마다 useEffect
로 새로고침할때마다 mutate하도록 추가해주었다.
원래는 클라이언트에서 쿠키를 삭제하는 방식으로 하려 했는데 httpOnly 를 true를 해놓으면 삭제도 안되어서 서버에서 쿠키를 삭제하는 방식을 사용했다.
그래서 간단하게 api 호출만 하면 되서 간단하게 구현할 수 있었다.
body가 필요 없어서 get으로 호출했다.
service/user.ts
export const mutateSignOut = () => {
const url = `logout api`;
return axios.get<IResponseAuth>(url).then((res) => {
return res.data;
});
};
hook/use-mutate-refreshing.ts
export const useMutateSignOut = (
mutateFunction: () => Promise<IResponseAuth>
) => {
const navigate = useNavigate();
const { mutate, data } = useMutation('signout', mutateFunction, {
onSuccess: (data) => {
axios.defaults.headers.common['Authorization'] = '';
navigate({
pathname: '/signin',
});
},
onError: () => {},
});
return { mutate, data };
};
서버의 데이터를 조회만 하는게 아니라고 생각해서 useMutate를 사용했다.
로그아웃이기 때문에 헤더를 비워주고 로그인 페이지로 넘어가도록 설정했다.