WerkzeugでBasic認証

ふと思い立ってWerkzeugでBasic認証してみた。BasicAuthMiddlewareBasic認証を行い、認証が通ったらappに処理を移譲する。

WerkzeugではHTTPヘッダに対応するクラスがあり、Authorizationヘッダーの情報はRequest.authorizationで、WWW-Authenticateヘッダーの情報はResponse.www_authenticateで取得、設定できる。

# -*- coding: utf-8 -*-

from werkzeug.wrappers import Request, Response

class BasicAuthMiddleware(object):

    def __init__(self, app, config):
        self.app = app
        self.username = config['username']
        self.password = config['password']

    def __call__(self, environ, start_response):
        request = Request(environ)
        autorization = request.authorization
        if autorization is not None and \
               autorization.username == self.username and \
               autorization.password == self.password:
            return self.app(environ, start_response)
        else:
            response = Response("Authorization Required", mimetype='text/plain', status=401)
            response.www_authenticate.set_basic(realm='authentication required, please input username/password')
            return response(environ, start_response)
    

class App(object):

    def __call__(self, environ, start_response):
            response = Response("Hello!", mimetype='text/plain')
            return response(environ, start_response)


def create_app():
    app = App()
    app = BasicAuthMiddleware(app, {
        'username': 'trot.thunder',
        'password': 'gmail.com',
    })
    return app


if __name__ == '__main__':
    from werkzeug.serving import run_simple
    app = create_app()
    run_simple('127.0.0.1', 5000, app, use_debugger=True, use_reloader=True)