LoginSignup
0
0

More than 1 year has passed since last update.

GAEへのファイルアップロードで気付きにくい落とし穴にハマった件

Last updated at Posted at 2022-12-02

TL;DR

  • GAEへのファイルアップロードにはサイズ制限があるよ
  • 制限を超えるアップロードはGCSの"署名付きURL"を使おう
  • そのときはドメイン(CORS)制限に気を付けましょう

やりたいこと

GAEでWebアプリケーションをホストして、ファイルをアップロードしてGCSへ格納、それをトリガとしてCloudFunctionsでごにょごにょしたい
image.png

  1. クライアントからGAEへファイルをPOST
  2. アップロードされたファイルをGAEからGCSへ転送( Google API )する
  3. その後はGCSのファイル格納イベントをトリガとしてファイル処理をFunctionsに任せる...

このやり方だと、ユーザ認証や認可がGAE1か所でシンプルだしなにより一般的なファイルPOSTプラスGCSのAPIで実装できるので簡単!
動作確認もOK!

の、はずでしたが...

なぜかエラーに

ユーザテスト実施で、「ファイルがアップロードできないんだけど」との報告が
image.png
ファイルサイズがでかすぎるですって?!

なるほど。GAEへのリクエストのサイズ制限があるのね。確かに動作確認では数KBのファイルしか使ってなかったカモ。

でも直接GCSへアップロードさせるのもセキュリティを緩めたくないしなぁ。。。

署名付きURL!

ありました!Google推奨プラクティス「署名付きURL」!
image.png
これでOK!
つまりこう、
image.png

  1. クライアントからGAEへ「こんなファイルをアップロードするよ!」とリクエスト
  2. GAEは受信したファイル情報を基にGCSから「署名付きURL」を取得して
  3. クライアントへその「署名付きURL」を通知
  4. クライアントからファイル実体をその「署名付きURL」へPUT
  5. めでたくサイズ制限なしでアップロードが完了して後続の処理へ...

てなわけです。

ちょっと処理が複雑になるとともに、UIを変えずに変更となるとAjaxを使うことになるものの、Google推奨プラクティスでセキュアに実装できますね!

あぁよかった。

さて、動作確認。

え?403って?

署名付きURLへファイルをPUTしようとすると、今度はGCSから403(forbidden)エラーになってる!
Googleの嘘つき~

これは、CORS(オリジン間リソース共有)違反なのね。
つまりは、GAEでホストされているドメイン(大抵自分で取得した)と、GCSの署名付きURLのドメイン(GCSから払い出される)が異なっていて(そらそうだ)、それをGCSはデフォルトで許容しない設定になっているのね。Googleごめんなさい。

GCSのバケットにCORSを構成する

対象が分かれば対応はJustDoIt!
もちろん公式サイトにも記述があります。Googleありがとう!
つまりはGCSへPUTリクエストを出す側のドメイン(この例だとGAEのドメインね)からのアクセスを許してやる。てことね。

この構成は対象のGCSバケットに1度設定してやればOKなので、

  • コマンドラインから手で実行してやってもいいけど、
  • IaCとしてバケット作成時に自動で構成してもいいし、
  • 環境ごと(本番/ステージング/開発)の差異(つまりはクライアントのドメイン)を一か所で管理したければGAEのアプリで最初に構成してやるって手もあるよね。(これだとローカルでGAEシミュレータから動かすときに再構成しやすいしね)

...なんてやり方で構成してやればOK。

皆さんご唱和ください!

「アップエンジン(GAE)へのアップロードは、サイズに注意、ドメイン注意」

私のハマった経験が皆様の良いDX(Developer Experience)の助けになれば幸せです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0