📑
Firebase Accessトークン期限切れ更新 x Axios
概要
以前書いた、「Nuxt.js(SSR) + Firebase Authenticationまとめ」で取得したAccess_Tokenなどが切れている場合にどのようにリフレッシュをするかなどを記事にしました。
環境に関して!
Backend(Middlware含む)は、割愛させていただきます。
トークン切れ判定と、トークンを更新
access_tokenが切れている場合の判定
onError
エラーが発生した時に発生するイベントを利用して、エラーの時の処理を始めます。
status code 401
が返ってきて、さらに詳しい条件分岐で"Token has expired"が返ってきたらトークンが切れているとわかるのでトークン更新処理を実行します。
access_tokenをrefresh_tokenで更新する
Nuxt/Firebase
では、リフレッシュトークンを利用した説明が具体的になかったので以下の方法で実装しました。詳しいHeader・Body情報は公式ドキュメントからチェックしてみてください!
再度リクエスト
再度同じリクエストを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トークンの更新
Discussion
初めまして。
当記事、大変参考になり助かりました。
参考にしつつ、コードを書いていたのですが、トークンのリフレッシュ処理がどうにもうまく動かない状況にあります。
もし、すぐお分かりになるようでしたらご教授いただければ大変助かります。
※firebaseの「https://securetoken〜」へのリクエストが上手くいかないため、当処理を抜き出して実行しているのですが、同一エラーとなります。
【firebaseへの更新リクエスト抜粋した処理】
refresh() {
const params = new URLSearchParams()
params.append('grant_type', 'refresh_token')
params.append('refresh_token', localStorage.getItem('refresh_token'))
this.$axios
.post(
https://securetoken.googleapis.com/v1/token?key=${process.env.FIREBASE_API_KEY}
,params,
{}
)
.then((response) => {
console.log('リフレッシュ成功' + 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)
})
.catch(() => {
console.log('リフレッシュエラー' + params)
})
},
【firebaseからのレスポンス内容】
error: {code: 401,…}
code: 401
message: "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project."
status: "UNAUTHENTICATED"
Google Chromeでリクエスト内容を確認したのですが、key、grant_type、refresh_tokenは正常に設定されてリクエストが送られているように見えます。
宜しくお願いいたします。