LoginSignup
0
0

fake-gcs-serverでは署名付きURLを発行しなくてよい

Last updated at Posted at 2024-01-06

あらすじ

GoogleのIdentity PlatformやCloud Storageを使ったアプリ開発をしていると、複数のエンジニア間でデータの衝突や相違が起きることがある。例えばデータベースには登録されているが、Cloud Storageには登録されていないとかその逆とか、名前が重複しちゃったとか。

こういう場合ローカルの開発環境でエミュレーターを使うという方法があるのだが、Identity PlatformやCloud Storageは公式のエミュレーターが存在しない。
なので大抵の場合はFirebase Emulatorを使うことになる。
これについては firebase emulator docker でググればそれなりに情報量の多いブログや記事が出てくるので参考にすればなんとかなる。
参照してもらうとわかるのだが、実はそんなにすんなり導入できるわけではなく、それなりにDockerの知識が要求される。

ということで、他にもう少し楽な選択肢はないかと検索すると、 fake-gcs-server というものが出てくる。今回はこの謎いエミュレーターでCloud Storageをエミュレートしてみる。

導入

以下の記事を参考に。

docker-compose.yml
・
・
(その他の記述)
・
・
cloud-storage:
    container_name: local-cloud-storage
    image: fsouza/fake-gcs-server:latest
    tty: true
    ports:
      - "4443:4443"
    volumes:
      - ./tmp/cloud-storage/data:/data
      - ./tmp/cloud-storage/storage:/storage
    command: -scheme http -public-host ${URL:-localhost}:4443

非常に簡単ではあるが、コマンド引数とvolumesの説明をする。

  • - ./tmp/cloud-storage/data:/data
    例えば./tmp/cloudstorage/dataの下に test というディレクトリを作るとそれがバケットになる。

  • - ./tmp/cloud-storage/storage:/storage
    アプリからファイルをアップロードするとこのstorageにファイルが溜まっていく。

  • -scheme http
    httpでのアクセスを許可する

  • -public-host ${URL:-localhost}:4443
    localhost:4443 をホストに設定する

これらを総合すると、アップロードしたファイル(例えばtest.txt)には以下のURLでアクセスするとブラウザで表示orダウンロードできる。

http:localhost:4443/バケット名/test.txt

署名付きURLの発行

ようやく本題。公式ドキュメントには以下のように記述されている。

Using with signed URLs
It is possible to use fake-gcs-server with signed URLs, although with a few caveats:

  • No validation is made on the query params (signature, expiration ...)
  • You need your client to modify the URL before passing it around (replace storage.googleapis.com with something that points to fake-gcs-server)
  • You need to configure fake-gcs-server to accept this local URL (by setting -public-host)

正直わけがわからないので実際に試した結果何が言いたいのかを超訳すると 署名付きURLはURLに署名するだけなんでアプリの機能じゃない。-public-host に指定したURLで直接ファイルにアクセスしてちょ である。

TypeScript + Node.jsでの実装例

つまりこういうこと。

client.ts
import { Storage } from '@google-cloud/storage';

import type { GetSignedUrlConfig } from '@google-cloud/storage';

// NODE_ENVがproduction以外の場合はfake-gcs-serverを使用する
const storage = process.env.NODE_ENV !== 'production'
  ? new Storage({
    apiEndpoint: 'http://localhost:4443',
    projectId: 'test',
  })
  : new Storage({
    keyFilename: rocess.env.GOOGLE_APPLICATION_CREDENTIALS
    projectId: process.env.GCP_PROJECT_ID,
  });

const bucketName = process.env.GCS_BUCKET_NAME || 'your-bucket-name';

const getSignedUrl = async (filePath: string): Promise<string> => {
  try {
    // NODE_ENVがproduction以外の場合はローカルのURLをそのまま返す
    if (process.env.NODE_ENV !== 'production') {
      const signedUrl = `http://localhost:4443/${bucketName}/${filePath}`;
      return signedUrl;
    }
    const [signedUrl] = await storage
      .bucket(bucketName)
      .file(fileName)
      .getSignedUrl();
    return signedUrl;
  }
  catch (error) {
    throw error;
  }
};

ドキュメントにも明確には載ってないけどこれでOKらしい。
ちなみに無理に署名付きURLを発行しようとすると以下のエラーが発生してしまう。

 Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
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