개발자
안녕하세요. 현재 개발 서버에서 게스트 모드 로그아웃 시 delete 요청을 보내는 플로우인데 일반 회원 계정 삭제와 동일한 api를 사용하고 있습니다. 일반 회원 계정 삭제는 잘 되는데 게스트 모드로 로그인을 하고 delete 요청을 보내면 헤더에 토큰이 안 담겨져 401 에러가 납니다... 현재 next.js를 사용하고, api 관련 로직은 class로 로컬 스토리지에서 엑세스 토큰과 리프레쉬 토큰을 가져오고, axios instance를 사용하여 headers에 토큰을 넣어 요청을 하고 있습니다. 로컬 스토리지에는 토큰들이 잘 보이고, 똑같은 api를 사용하는데 왜 이런 이슈가 생기는지 모르겠습니다 ㅜㅜ...
답변 1
안녕하세요 axios instance 쪽 코드가 있으면 더 정확한 답변 가능할 거 같습니다. 의심가는 바로는 혹시 인스턴스 생성 시에 헤더에 토큰을 삽입 중이라고 하시면 api를 호출 하는 시점이 아닌 생성하는 시점에서 토큰을 넣어두기에 그 시점에 storage에 토큰이 없으면 비어보일 거 같습니다.
도연
작성자
웹 개발자 • 2023년 12월 08일
안녕하세요 답변 감사합니다 :) 아래는 aixos instance 와 interceptors 코드 입니다! 말씀하신대로 시점 문제라면 제가 짐작하기로는 일반 회원이 delete 요청을 할때는 /history 라는 도메인으로 이동 후 탈퇴 버튼을 눌러 delete 요청을 할 수 있어서 잘 되었던 거 같은데 게스트 모드는 헤더에서 바로 로그아웃 버튼을 눌러 delete 요청 할 수 있어서 바로 요청을 보내서(?) 안되는거 같긴 합니다... import axios, { AxiosResponse } from 'axios'; import LocalStorage from './localStorage'; const token = LocalStorage.getItem('user-key'); const accessToken = typeof window !== 'undefined' ? token.state.accessToken : null; const refreshToken = typeof window !== 'undefined' ? token.state.refreshToken : null; export const instance = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_URL, headers: { Authorization: accessToken, Refresh: refreshToken, }, withCredentials: true, }); const storageData = LocalStorage.getItem('user-key'); const parseJWT = (token: string | null) => { if (token) return JSON.parse(atob(token.split('.')[1])); }; const authVerify = () => { const decodedAccess = parseJWT(accessToken); const decodedRefresh = parseJWT(refreshToken); if (decodedAccess?.exp * 1000 < Date.now()) { return 'Access Token Expired'; } if (decodedRefresh?.exp * 1000 < Date.now()) { return 'Refresh Token Expired'; } return true; }; const onFulfiled = async (response: AxiosResponse) => { if (authVerify() === 'Access Token Expired') { const { authorization: newAccessToken } = response?.headers; storageData.state.accessToken = newAccessToken; LocalStorage.setItem('user-key', JSON.stringify(storageData)); response.config.headers = Object.assign({}, response.config.headers, { authorization: `${newAccessToken}`, refresh: refreshToken ?? '', }); return await axios(response.config); } return response; }; instance.interceptors.request.use( async (config) => { config.headers = config.headers ?? {}; if (accessToken) { config.headers.Authorization = `${accessToken}`; } return config; }, (error) => Promise.reject(error), ); instance.interceptors.response.use(onFulfiled, (error) => { return Promise.reject(error); });
김인후
software engineer • 2023년 12월 08일
음... 말씀 주신 게 로그아웃 버튼을 누르면 로그아웃 로직 후에 delete 요청을 준다는 말씀이실까요? instance.interceptors.request.use( async (config) => { config.headers = config.headers ?? {}; if (accessToken) { config.headers.Authorization = `${accessToken}`; } return config; }, (error) => Promise.reject(error), ); 해당 request interceptor 부분에서 console.log로 accessToken의 유무를 찍어보면서 하는 것도 좋을 거 같습니다
도연
작성자
웹 개발자 • 2023년 12월 08일
네! 로그아웃 버튼을 누르면 바로 delete 요청이 가게 했습니다 instance.interceptors.request.use 바깥 바로 위에서 console.log를 출력했을 땐 토큰이 잘 출력이되는데... 말씀해주신대로 if문 안에 console.log(accessToken)해서 출력해봤는데 빈칸으로 출력이 되드라구요...
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
지금 가입하면 모든 질문의 답변을 볼 수 있어요!