[React] class λ₯Ό μ¬μ©ν μ μ μν accessToken
React μ±μμ login ν accessToken μ μλ²λ‘λΆν° λ°κΈλ°μ μ μ μνλ‘ κ΄λ¦¬νμ¬ μΈμ¦μ΄ νμν api μμ²μλ§λ€ header μ λ£μ΄μ€ λ κ²ͺμλ troubleshooting κΈ°λ‘μ λλ€.
μΉμμ μΈμ¦ κΈ°λ₯μ ꡬννλλ°, λ‘κ·ΈμΈ μ±κ³΅ ν μλ²λ‘λΆν° λ°μ accessToken μ μ μ₯ν κ³³μ΄ νμνλ€. μ²μμλ λΈλΌμ°μ localStorage μ μ μ₯μ νλ €κ³ νλλ° νμ·¨ μνμ΄ λμ κ² κ°μ μ± μ μ μνμ μ¨κ²¨λκ³ μΈλΆμμ νμ·¨ν μ μλλ‘ κ΅¬νκ³νμ λ°κΎΈμλ€.
μ μ μν: Recoil μ μΈκΉ? β μ λλ€.
ν λ΄μμ μ μ μνλ Recoil λΌμ΄λΈλ¬λ¦¬λ₯Ό μ°κΈ°λ‘ κ²°μ νμκΈ° λλ¬Έμ μ²μμλ Recoil λ‘ ν΄λ³΄λ €κ³ νμΌλ μ€ν¨νλ€. Recoil μ React hook κΈ°λ°μ΄μ΄μ React component κ° μλ κ³³μμλ μΈ μ μκΈ° λλ¬Έμ accessToken μ μ μ₯νλ μ©λλ‘ μ¬μ©ν μ μμλ€.
api request λ₯Ό νκΈ° μ μ λͺ¨λ μμ²μ΄ ν ν¨μλ₯Ό ν΅ν΄μ κ°λλ‘ util ν¨μλ₯Ό λ§λ€μ΄ λμλλ°, μ΄ ν¨μμμ header μ Bearer ${accessToken} μ λ£μ΄μ£ΌκΈ° μν΄μλ μ μ μνμ μ μ₯λμ΄ μλ access Token μ μ½μ΄μ¬ μ μμ΄μΌ νλ€. κ·Έλ°λ° μ΄ ν¨μλ React component κ° μλκΈ° λλ¬Έμ recoil μ μ¬μ©ν μ μμλ€.
ν΄κ²°: AccessToken class λ‘ λ§λ€μ΄μ μ°μ.
λ‘κ·ΈμΈ ν μλ²λ‘λΆν° λ°κΈλ°μ accessToken μ μ μ₯ν AuthToken class λ₯Ό λ§λ λ€.
class AuthToken { private _token: string; constructor() { this._token = ""; } getToken() { return this._token; } setToken(newToken: string) { this._token = newToken; } } export const authToken = new AuthToken();
μ±μ΄ μ€νλ λλ§λ€ μ΄ AuthToken class λν μλ‘ μμ±λλ€. νμ΄μ§κ° 리λ‘λ λ λλ§λ€ μ±μ μ¬μ€νλλλ°, μ΄λλ§λ€ μλ‘ token μ κ°±μ ν μ¬λ°κΈ λ°λλ‘ κ΅¬νν κ²μ΄λΌμ AuthToken class μ token κ°μ΄ μ΄κΈ°νλμ΄λ μκ΄μ΄ μλ€.
λμ μ±μ΄ 리λ‘λ λκΈ° μ κΉμ§λ μ΄ class λ νλ²λ§ μμ±λμ΄ this._token μ λ³κ²½ν μ μλ κ²μ setToken λ©μλλ₯Ό μ€νμμΌ°μ λ λΏμ΄λΌ μμ νλ€.
μ΄μ authToken.setToken(accessToken); μ sign-in μ½λ λ€μ μ€μ λ£μ΄μ£Όλ©΄ μ μμνλ‘ accessToken μ κ°μ§ μ μκ² λκ³ , accessToken μ΄ μμ΄μΌλ§ νΈμΆν μ μλ api λ€μ νΈμΆν λ getToken μΌλ‘ κ°μ Έμ Authorization header μ λ£μ΄μ£Όλ©΄ λλ€.
axios κ³΅ν΅ ν¨μ μμ
export const request = async ({ ...options }: any) => { let accessToken = authToken.getToken(); // validate accessToken expiration if (accessToken && parseJwt(accessToken).exp < Date.now() / 1000) { // accessToken λ§λ£μ refresh token μΌλ‘ μ¬λ°κΈ const response = await axiosInstance.post("/auth/refresh", { deviceId: localStorage.getItem("deviceId"), }); accessToken = response.data; authToken.setToken(accessToken); } // axiosμ withCredentialsλ₯Ό trueλ‘ μ€μ ν΄μ€μΌ refreshToken cookieλ₯Ό μ£Όκ³ λ°μ μ μλ€. axiosInstance.defaults.withCredentials = true; axiosInstance.defaults.headers.common[ "Authorization" ] = `Bearer ${accessToken}`; const onSuccess = (response: any) => response; const onError = (error: any) => { ... error flow throw error; }; try { const response = await axiosInstance(options); return onSuccess(response); } catch (error) { return onError(error); } };