Djangoでプロジェクト全体に独自のBasic認証をかける方法
Djangoのプロジェクトを使っていてBasic認証をかける方法はいくつかあると思うが、今回は「django-basicauth」を利用する。
https://pypi.org/project/django-basicauth/
基本的にはドキュメントにあるようにViewごとにデコレータを付けるかミドルウェアでプロジェクト全体にBasic認証をかけることができる。(どちらもimportして必要な記述を足すだけなので非常に簡単)
しかし場合によっては認証をかけるか、かけないかを細かく設定したい時がある(例えばテストやAPIなどではBasic認証をかけたくないなど)。このような時には既存のコードを少し修正する必要がある。今回はミドルウェアを使ってページ全体にBasic認証をかけるが基本的にはデコレータを使う場合も同様の修正をすれば良い。
ライブラリのソースコードを見ると以下のようにDjangoのミドルウェアを実装していた。
class BasicAuthMiddleware(MiddlewareMixin): def process_request(self, request): if not validate_request(request): return HttpResponseUnauthorized() return None
django-basicauth/middleware.py at master · hirokiky/django-basicauth
(ミドルウェアについては以下を参照:https://office54.net/python/django/django-middleware-about#section1-1)
このミドルウェアでprocess_requestというメソッドが呼ばれているが、Djangoの公式ドキュメントを参照すると以下のように書いてある。
The
__call__()
method:
- Calls
self.process_request(request)
(if defined).- Calls
self.get_response(request)
to get the response from later middleware and the view.- Calls
self.process_response(request, response)
(if defined).- Returns the response.
ミドルウェアではリクエストごとに__call__()
メソッドがフックされるがprecess_requestが定義されている場合はViewを呼び出す前に実行してくれる。
そのため上のライブラリのソースコードではprecess_requestをオーバーライドしてvalidate_requestメソッドで認証のチェックを行っている。
以上のようにライブラリがBasic認証をかけていることが分かったのでもし追加の機能を加えたい場合は以下のようにすればよい。
class BasicAuthMiddleware(MiddlewareMixin): def process_request(self, request): # 追加 # テストの時にはBasic認証をかけない if TESTING: return None # ライブラリと同じ if not validate_request(request): return HttpResponseUnauthorized() return None
以上に加えてsettins.pyにBasic認証の設定を記述する。