認証必須の URL は app.yaml ではなくデコレータで記述

Google App Engine(以下 GAE)で、ある URL をログイン必須や管理者専用にする方法として、app.yaml で指定する方法があります。でもこの方法だと、RequestHandler のコードを見たとき、ログイン必須なメソッドなのかが分らないので、好きじゃないです。

「ログイン必須」とか「管理者専用」といったコメントを記述する手もありますが、書き忘れ・修正忘れが発生する可能性があるので、スマートじゃないですよね。

私の場合、認証が必要な URL は、対応する RequestHandler のメソッドにデコレータを付けています。ログイン必須の場合は google.appengine.ext.webapp.util にある login_required を指定。GET 以外のメソッドでも指定したい場合は自作の login_required。

「管理者のみ」のデコレータは用意されていないので、これは admin_required デコレータを自作しています。

from google.appengine.api import users
from google.appengine.ext import webapp

def admin_required(original_func):
    def decorated_func(self, *args, **kwargs):
        if not users.get_current_user():
            self.redirect(users.create_login_url(self.request.uri))
            return
        if not users.is_current_user_admin():
            self.error(401)
            return
        return original_func(self, *args, **kwargs)
    return decorated_func

class MainHandler(webapp.RequestHandler):
    @admin_required
    def get(self):
        self.response.out.write("Hello")

app.yaml にまとめて書くか、デコレータを使ってハンドラのすぐそばに書くかは、好みが分かれるところです。個人的には、メソッドの実装と同じ場所に「認証が必要」といった情報を記述したいかな。ソースコードをいじれない TaskQueue や defferd は例外ですけど。