#daiizメモ

Scrapboxに夢中

Google App Engine/Python, Google Cloud Storage で特定のユーザーのみに画像を返す

Google App Engine / Python と Google Cloud Storage を使って,HTTP/GETでリクエストをもらったときに,特定のユーザーだけにコンテンツを返却する仕掛けを作る.

  • 「特定のユーザー」であるかどうかはGoogleアカウントでログイン中のユーザーのGmailアドレスで判断する.
  • 「コンテンツ」はどのようなファイルでもOK.今回は画像を用いる.

ざっくりとした手順とプログラムを紹介する.

GCS にファイルを置いておく

プログラムで画像を生成させてGCSに保存したり,コマンドラインからアップロードしたりできるけれど,今回はウェブUIで操作してファイルを保存する. f:id:daiiz:20160727013102p:plain:w450

GAE のプログラムを書く

メインの部分だけ載せます.

from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers

# コンテンツにアクセスできるユーザーのGmailアドレス
MASTER_USERS = []

def is_master_user(user):
    if user is None:
        return False
    return user.email() in MASTER_USERS

# 予め登録されたユーザーのみにコンテンツを返却する
class GCSServingHandlerPrivate (blobstore_handlers.BlobstoreDownloadHandler):
    # /gs-p/<BUCKET_NAME>/<DIR_NAME>/<FILE_NAME>
    def get (self, bucket_name, dir_name, file_name):
        user = users.get_current_user()  # ログイン中のユーザー情報がわかる
        if is_master_user(user):
            blob_key = blobstore.create_gs_key('/gs/%s/%s/%s' % (bucket_name, dir_name, file_name))
            self.send_blob(blob_key)
        else:
            # 登録されていない場合は代わりの画像を返す
            blank_key = blobstore.create_gs_key('/gs/daiiz-bucket-1/public/illust.png')
            self.send_blob(blank_key)

あとはwebapp2.WSGIApplicationのルーティングの設定を追加する.

app = webapp2.WSGIApplication([
    ...
    ('/gs-p/(.+)/(.+)/(.+)', GCSServingHandlerPrivate),
    ...
])

アクセスしてみる

以下に,実際に https://daiiz-apps.appspot.com/gs-p/daiiz-appspot/test/sushi.jpg<img>で読み込んでみる.

僕は「予め登録されたユーザー」に含まれているので,京都の寿司の写真が見られるけれど,僕以外の人がアクセスした場合はキャラクターのイラストが写っていれば大成功.

感想

GAEとGCSは触っていて楽しい