Firebase Accessトークン期限切れ更新 x Axios

2 min read読了の目安(約2000字

概要

以前書いた、「Nuxt.js(SSR) + Firebase Authenticationまとめ」で取得したAccess_Tokenなどが切れている場合にどのようにリフレッシュをするかなどを記事にしました。

https://zenn.dev/watson_sei/articles/f4db7312494525

環境に関して!

Backend(Middlware含む)は、割愛させていただきます。

下記の図が今回の仕組みです。急いで作ったのでわかりづらいですがまあぱっと見で理解してください

トークン切れ判定と、トークンを更新

access_tokenが切れている場合の判定

onErrorエラーが発生した時に発生するイベントを利用して、エラーの時の処理を始めます。
status code 401が返ってきて、さらに詳しい条件分岐で"Token has expired"が返ってきたらトークンが切れているとわかるのでトークン更新処理を実行します。

access_tokenをrefresh_tokenで更新する

Nuxt/Firebaseでは、リフレッシュトークンを利用した説明が具体的になかったので以下の方法で実装しました。詳しいHeader・Body情報は公式ドキュメントからチェックしてみてください!

https://firebase.google.com/docs/reference/rest/auth/#section-refresh-token

再度リクエスト

再度同じリクエストをaxiosで書くのはめんどくさいので、axios(error.config)で簡単に再リクエストを実装しちゃいます。

plugins/axios.js
import axios from "axios";

export default function ({ $axios, redirect }) {
  $axios.onError(error => {
    if (error.response.status === 401) {
      if (error.response.data.message === "Token has expired") {
        const params = new URLSearchParams();
        params.append("grant_type", "refresh_token")
        params.append("refresh_token", localStorage.getItem('refresh_token'))
        axios.post(`https://securetoken.googleapis.com/v1/token?key=${process.env.apiKey}`, params, {
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
          }
        }).then((response) => {
          localStorage.removeItem('access_token')
          localStorage.setItem('access_token', response.data.access_token)
          localStorage.removeItem('refresh_token')
          localStorage.setItem('refresh_token', response.data.refresh_token)
          axios(error.config)
        }).catch(() => {
          redirect('/room')
        })
      }
    }
  })
}

参考

Nuxt.jsでaxiosのリクエストをフックする
Firebase Auth の refreshトークンの取得とIDトークンの更新