前提
DjangoとReactにてJWTをCookieに保存する認証を実装しているが、リフレッシュトークンの更新がうまくいかない
実現したいこと
・トークンが切れた時点でリフレッシュトークンを取得し、認証をクリアする
発生している問題・エラーメッセージ
https://qiita.com/shitikakei/items/d818fb0aa8670aa4228c#authenticationpy https://www.miracleave.co.jp/contents/1654/react-jwt-axios-interceptors/ こちらのページを参考に、Django側でCookieをResponseヘッダーにセットし、認証を行うところまでは実装できました。 しかし、アクセストークンの期限が切れた時にリフレッシュトークンを取得し、自動更新を行う操作がうまくいきません。 トークンが切れた状態でリロードを行なってもトークンの取得は行われず、再度ログイン認証を行う必要があります。
該当のソースコード
React
1//ログイン時は以下のフックを使用してPOSTリクエストを行なっています。 2const useAuthAxios = () => { 3 const refresh = useRefreshToken(); 4 const { auth } = useContext(AuthContext); 5 const { cookies } = useContext(AuthContext); 6 7 useEffect(() => { 8 // リクエスト前に実行。headerに認証情報を付与する 9 const requestIntercept = authAxios.interceptors.request.use( 10 (config) => { 11 return config; 12 }, 13 (error) => Promise.reject(error) 14 ); 15 16 // レスポンスを受け取った直後に実行。もし認証エラーだった場合、再度リクエストする。 17 const responseIntercept = authAxios.interceptors.response.use( 18 (response) => { 19 //console.log(response) 20 return response; 21 }, 22 async (error) => { 23 if (error.response.status === 401) { 24 // 新しくaccess_tokenを発行する 25 await refresh(); 26 return refresh.response(error.config); 27 } else { 28 return Promise.reject(error); 29 } 30 } 31 ); 32 33 return () => { 34 // 離脱するときにejectする 35 authAxios.interceptors.request.eject(requestIntercept); 36 authAxios.interceptors.response.eject(responseIntercept); 37 }; 38 39 },[auth, refresh]) 40 41 return authAxios; 42 43}; 44 45export default useAuthAxios; 46 47//refresh_tokenを元にaccess_tokenを取得するフック 48const useRefreshToken = () => { 49 const { setAuth } = useContext(AuthContext); 50 const { cookies } = useContext(AuthContext); 51 const navigate = useNavigate(); 52 53 const refresh = async () => { 54 55 // cookieに保存されたrefresh_tokenを送付してaccess_tokenを取得する 56 //authAxiosだとタイムアウト 57 axios.defaults.xsrfCookieName = "csrftoken" 58 axios.defaults.xsrfHeaderName = "X-CSRFTOKEN" 59 60 const res = await axios 61 .post("http://localhost:8000/api/auth/refresh", 62 {}, { 63 headers: 64 { 65 "X-CSRFTOKEN": cookies.get("csrftoken"), 66 "Content-Type":"application/json" 67 }, 68 withCredentials:true, 69 }); 70 const refreshToken = res.data["refresh"] 71 const response = await axios.post("http://localhost:8000/api/auth/newtoken", 72 { 73 "refresh":refreshToken 74 }, 75 { 76 withCredentials:true 77 } 78 ); 79 setAuth((prev) => { 80 return { ...prev, response}; 81 }); 82 return response; 83 }; 84 return refresh; 85}; 86 87export default useRefreshToken;
試したこと
refreshの取得が出来ていることは確認できました。以下でリフレッシュが動作することも確認済みです。以下のエンドポイントはSet-Cookieを含むHttpResponseオブジェクトを返します。
React
1 const response = await axios.post("http://localhost:8000/api/auth/newtoken", 2 { 3 "refresh":refreshToken 4 },
Responseオブジェクトの受け取り方やuseEffectの使い方が間違っているのかと思い、いろいろ試してみましたがうまくいきませんでした。
リクエスト時にトークンの期限が切れていた場合にそのResponseオブジェクトを利用してCookieをセットし、再度アクセスを行いたいのですが難しいのでしょうか?
ログイン時はSet-Cookieを含むオブジェクトにリクエストを投げることで、以下のようなコードで認証に成功しています。
React
1 const login = async (payload) => { 2 await authAxios 3 .post("/api/auth/login",payload) 4 navigate("/main") 5 };
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー