作成: 2021年08月12日
更新: 2021年08月12日
Ruby on Rails + Next.js + Firebase authの構成でアプリの認証部分を実装していてWSL+Dockerでローカル開発しているときにFirebase ID token has invalid signature. Invalid iat
のエラーが出てうまく認証できないときがあった.
RubyにはFirebaseの公式SDKがないため以下の2記事を参考に自前でFirebaseのJWTトークン認証を実装していた.
RubyでFirebaseのidトークンを認証に使ってみる - Qiita
Rails+Firebase認証のサンプルアプリ - Qiita
エラーメッセージの箇所を調べると以下のJWT.decode
の部分でInvalid iat
が原因で失敗しているようだった.
def _decode_token(token, key=nil, verify=false, options={})
begin
decoded_token = JWT.decode(token, key, verify, options)
rescue JWT::ExpiredSignature => e
raise 'Firebase ID token has expired. Get a fresh token from your client app and try again.'
rescue => e
raise "Firebase ID token has invalid signature. #{e.message}"
end
{
payload: decoded_token[0],
header: decoded_token[1]
}
end
厄介なことに発生するときとしないときがあった.
JWTのiatはJWTトークンが発行された時間を表していてこれは過去の時点であることが必要です.
つまりJWTトークンの発行はFirebaseのサーバーで行われるので発行時間そのものは正しいとするとローカルのサーバーの時刻が遅れている可能性が高い.
そこで調べてみるとWSLはPCのスリーブ時などで時刻のずれが起きることがあるそうでこれが原因っぽいです.(以下の記事では時刻のずれでapt-getが失敗しています)
解決策としては以下のコマンドでWSLをシャットダウンすることです(自動で再起動される)
wsl --shutdown
ディストリビューションの再起動ではwsl -t Ubuntu
では直ったり直らなかったりしたのでシャットダウンが確実です.
一度シャットダウンすればまたずれるまでしばらくはエラーが発生しません.