🩹
liffのIDTokenの有効期限切れ対策
課題
liff sdkのgetIDToken
で取得されるIDTokenはlocalStorageにキャッシュされるが、有効期限が切れても更新されないという問題があります。(ver2.1.13現在)
この問題はLINE DCのQ&Aでも報告されているものです。
対策
liff sdkはGitHubで公開されている訳ではなかったので、プルリクはできませんでした。
そこで、sdkが使っているlocalStorageの値を無理やり読み書きすることで対策することにしました。
通常の実装
まずは普通に実装した場合のコードです。
index.js(対策前)
const main = async (liffId) => {
await liff.init({ liffId })
const idToken = liff.getIDToken();
// idTokenをサーバに投げるなどの処理...
}
普通に動くんですが、動作確認終了後、半日後くらいに同じブラウザで再度動作確認するとサーバ側で400 Bad Requestエラーが発生します。
対策後の実装
次に対策をした際のコードです。
index.js(対策後)
// liff関連のlocalStorageのキーのリストを取得
const getLiffLocalStorageKeys = (prefix) => {
const keys = []
for (var i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i)
if (key.indexOf(prefix) === 0) {
keys.push(key)
}
}
return keys
}
// 期限切れのIDTokenをクリアする
const clearExpiredIdToken = (liffId) => {
const keyPrefix = `LIFF_STORE:${liffId}:`
const key = keyPrefix + 'decodedIDToken'
const decodedIDTokenString = localStorage.getItem(key)
if (!decodedIDTokenString) {
return
}
const decodedIDToken = JSON.parse(decodedIDTokenString)
// 有効期限をチェック
if (new Date().getTime() > decodedIDToken.exp * 1000) {
const keys = getLiffLocalStorageKeys(keyPrefix)
keys.forEach(function(key) {
localStorage.removeItem(key)
})
}
}
const main = async (liffId) => {
clearExpiredIdToken(liffId)
await liff.init({ liffId })
const idToken = liff.getIDToken()
// idTokenをサーバに投げるなどの処理...
}
liff sdkが下記のようなキーでlocalStorageを使っているので、その値を読みに行き、idTokenの期限が切れていたら、liff関連のlocalStorageのレコードを消してしまっています。
LIFF_STORE:{{YOUR_LIFF_ID}}:IDToken
LIFF_STORE:{{YOUR_LIFF_ID}}:accessToken
LIFF_STORE:{{YOUR_LIFF_ID}}:clientId
LIFF_STORE:{{YOUR_LIFF_ID}}:context
LIFF_STORE:{{YOUR_LIFF_ID}}:decodedIDToken
liff.init
の前にこの処理を挿入することで、常に有効なIDTokenを使うことができます。
最後に
sdk側で修正されるのがベストなのでLINEさん、修正お願いいたします!
Discussion