TL;DR
署名付きURLを生成する用のサービスアカウントのキーを明示的に設定する。
背景
CloudStorageにアップロードした動画からサムネイル画像を生成したく、
CloudFunctionsでアップロードのトリガーを使い生成する処理を実装していました。
以下のような感じのコードです。
https://github.com/firebase/functions-samples/blob/master/generate-thumbnail/functions/index.js
生成したサムネイル画像はCloudStorageにアップロードし、
署名付きURLを生成してデータベースに保存するようなものを実装していたのですが、
数日後に生成したURLが403で弾かれるようになってしまいました。
ちゃんとサンプルのように有効期限を設定していたのにです。
https://github.com/firebase/functions-samples/blob/8f599e4cc56ef849136982d19f4d9d5348d3dc58/generate-thumbnail/functions/index.js#L84-L92
// Get the Signed URLs for the thumbnail and original image.
const config = {
action: 'read',
expires: '03-01-2500',
};
const results = await Promise.all([
thumbFile.getSignedUrl(config),
file.getSignedUrl(config),
]);
原因
Issueに同様の現象の人がいました。
こちらのコメントによると、
サービスアカウントのキーは、一定の時間(5~7日)が経過すると削除されます。
とのことです。
CloudFunctionsには一時的なサービスアカウントがあるため、
CloudFunctionsにて署名したURLは「一定の時間(5~7日)」が立ってしまうとマッチしないということでした。
有効期限が短くてよければなんら問題ないのかなとおもいますが、
1日以上にする場合は保険もかねて別途サービスアカウントを明示的に設定してあげる必要がありそうです。
対応
こちらのコメントになります。
設定手順
サービスアカウントのキーの作成
-
GoogleCloudConsoleで
IAMと管理
を開きます。 -
左側のメニューから
サービスアカウント
を開きます。
IMAの追加
- GoogleCloudConsoleで
IAMと管理
を開きます。 - 左側のメニューから
IAM
を開きます。 - 先ほど追加したサービスアカウントのIAMを追加
- 以下ロールを設定
生成したキーをFunctionsの環境変数に定義
// jsonにあるprivate_key
firebase functions:config:set service_account.private_key=xxxxxxxx
// jsonにあるclient_email
firebase functions:config:set service_account.client_email=xxxxxxxx
// 設定されているか確認
firebase functions:config:get
FunctionsのStorageインスタンス生成のオプションを設定
// 環境変数を取得
const credentials = {
client_email: functions.config().service_account.client_email,
private_key: functions.config().service_account.private_key
}
// キーを設定してインスタンス生成
const gcs = new Storage({ credentials: credentials });
// 以降任意の処理
結果
この文章が更新されずにのこっているってことはきっと解決できたってことだろう...
参考
サービスアカウントのキーの作成
https://cloud.google.com/iam/docs/creating-managing-service-account-keys?hl=ja
Issue
https://github.com/googleapis/nodejs-storage/issues/244
https://github.com/googleapis/nodejs-storage/issues/244#issuecomment-403601209
GCP側の設定
https://qiita.com/harigel/items/665df7b1d806577b32de