Django 特定ビューのbasic認証をデコレータで

Djangoの特定のビューでbasic認証を使う。

全体で使うならmiddlewareを自作すれば良いが、特定ビューの時は、デコレータが楽だった。

まずは、app/decorators/basic_auth_decorator.pyを以下のような内容で作成する。

"""
`app/decorators/basic_auth_decorator.py`

A decorator for basic auth
"""

from django.http import HttpResponse
from django.contrib.auth import authenticate

import base64


def _http401():
    response = HttpResponse("Unauthorized", status=401)
    response['WWW-Authenticate'] = \
        'Basic realm="basic auth username/password inalid"'
    return response


def _basic_auth(request):
    if 'HTTP_AUTHORIZATION' not in request.META:
        return False
    (auth_scheme, base64_username_pass) = \
        request.META['HTTP_AUTHORIZATION'].split(' ', 1)
    if auth_scheme.lower() != 'basic':
        return False
    username_pass = base64.decodebytes(
        base64_username_pass.strip().encode('ascii')).decode('ascii')
    (username, password) = username_pass.split(':', 1)
    user = authenticate(username=username, password=password)
    return user is not None


def basic_auth(func):
    def wrapper(request, *args, **kwargs):
        if not _basic_auth(request):
            return _http401()
        else:
            return func(request, *args, **kwargs)

    return wrapper

これを、適用したいビューのところでデコレータ指定すればいい。下記は、post時に認証をする。

"""
app/views.py
"""

from .decorators.basic_auth_docorator import basic_auth

...

@method_decorator(basic_auth, name='post')
class SomeView(View):
    def post(self, request, *args, **kwargs):
        return HttpResponse('Hello post!')

参考:

  • Django basic auth - Qiita
    • basic認証がとても参考になる。viewsに認証を書きたくないので、今回の記事を残す。
タイトルとURLをコピーしました