ぷろぐら×でざいん

Django ユーザータイプでのログイン制限

Django ユーザータイプでのログイン制限

Django ユーザータイプでのログイン制限

久しぶりの投稿です。
気が付けばもう4月。桜も散り、多くの新社会人が誕生し、丁度5営業日が終了した感じですかね?
フリーランスを始めてから早くも2ヵ月間経ちましたが、紆余曲折がある中、何とか生きてます。主に新規プロダクト作りの為にひたすら基盤を整えています。


ユーザータイプでのログイン制限

pip install django-braces==1.12.0

をインストールし、LoginRequiredMixinを継承してUserTypeRequiredMixinを作成します。

from braces.views import LoginRequiredMixin


class UserTypeRequiredMixin(LoginRequiredMixin):
    user_type_required = None

    def dispatch(self, request, *args, **kwargs):
        has_permission = self.check_user_type(request)
        if not has_permission:
            return self.handle_no_permission(request)

        return super(UserTypeRequiredMixin, self).dispatch(
            request, *args, **kwargs)

    def check_user_type(self, request):
        if not self.user_type_required:
            return True

        return request.user.user_type == self.user_type_required



UserTypeRequiredMixinViewに入れる

user_type_requiredに任意のユーザータイプを代入することによって、そのユーザータイプと一致していないユーザーはログイン画面にリダイレクトされるようになります。

from django.http import HttpResponse, JsonResponse
from django.template import loader
from django.views import View

from ... import UserTypeRequiredMixin

ADMIN = 1


class Index(UserTypeRequiredMixin, View):

   user_type_required = Admin
    def get(self, request):
        template = loader.get_template('pages/index.html')
        context = {}
        return HttpResponse(template.render(context, request))

django-bracesの中身を少し参照

class AccessMixin(object):
    login_url = None
    raise_exception = False
    redirect_field_name = REDIRECT_FIELD_NAME  # Set by django.contrib.auth
    redirect_unauthenticated_users = False

    def get_login_url(self):
        login_url = self.login_url or settings.LOGIN_URL
        if not login_url:
            raise ImproperlyConfigured(
                'Define {0}.login_url or settings.LOGIN_URL or override '
                '{0}.get_login_url().'.format(self.__class__.__name__))

        return force_text(login_url)

    def get_redirect_field_name(self):
        if self.redirect_field_name is None:
            raise ImproperlyConfigured(
                '{0} is missing the '
                'redirect_field_name. Define {0}.redirect_field_name or '
                'override {0}.get_redirect_field_name().'.format(
                    self.__class__.__name__))
        return self.redirect_field_name

    def handle_no_permission(self, request):
        if self.raise_exception:
            if (self.redirect_unauthenticated_users
                    and not _is_authenticated(request.user)):
                return self.no_permissions_fail(request)
            else:
                if (inspect.isclass(self.raise_exception)
                        and issubclass(self.raise_exception, Exception)):
                    raise self.raise_exception
                if callable(self.raise_exception):
                    ret = self.raise_exception(request)
                    if isinstance(ret, (HttpResponse, StreamingHttpResponse)):
                        return ret
                raise PermissionDenied

        return self.no_permissions_fail(request)

    def no_permissions_fail(self, request=None):
        return redirect_to_login(request.get_full_path(),
                                 self.get_login_url(),
                                 self.get_redirect_field_name())

no_permissions_failがログイン失敗した際のリダイレクト処理をしていますね。
raise_exceptionTrueにすることでエラー扱いにもできるみたいですね。中身は結構単純なので自前で作っても問題ないかもですね。


あとがき

どのようなシステムでも管理者、一般ユーザーと最低2種類のユーザーがいるはずなので、こういうのを予め用意しておくと後々便利かもですねー。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です