web-dev-qa-db-ja.com

Django:login_requiredデコレータをサイト全体(静的メディアを除く)に適用するにはどうすればよいですか?

example は、アプリケーションレベルのビューのスニペットを提供しますが、テンプレートを含め、「urls.py」ファイルにさまざまな(およびアプリケーション以外の)エントリがたくさんある場合はどうなりますか?このlogin_requiredデコレータをそれぞれに適用するにはどうすればよいですか?

(r'^foo/(?P<slug>[-\w]+)/$', 'bugs.views.bug_detail'),
(r'^$', 'Django.views.generic.simple.direct_to_template', {'template':'homepage.html'}),
23
meder omuraliev

これをプロジェクトルートのmiddleware.pyファイルにドロップしました( http://onecreativeblog.com/post/59051248/Django-login-required-middleware から取得)

from Django.http import HttpResponseRedirect
from Django.conf import settings
from re import compile

EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
    EXEMPT_URLS += [compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]

class LoginRequiredMiddleware:
    """
    Middleware that requires a user to be authenticated to view any page other
    than LOGIN_URL. Exemptions to this requirement can optionally be specified
    in settings via a list of regular expressions in LOGIN_EXEMPT_URLS (which
    you can copy from your urls.py).

    Requires authentication middleware and template context processors to be
    loaded. You'll get an error if they aren't.
    """
    def process_request(self, request):
        assert hasattr(request, 'user'), "The Login Required middleware\
 requires authentication middleware to be installed. Edit your\
 MIDDLEWARE_CLASSES setting to insert\
 'Django.contrib.auth.middlware.AuthenticationMiddleware'. If that doesn't\
 work, ensure your TEMPLATE_CONTEXT_PROCESSORS setting includes\
 'Django.core.context_processors.auth'."
        if not request.user.is_authenticated():
            path = request.path_info.lstrip('/')
            if not any(m.match(path) for m in EXEMPT_URLS):
                return HttpResponseRedirect(settings.LOGIN_URL)

次に、settings.pyのMIDDLEWARE_CLASSESにprojectname.middleware.LoginRequiredMiddlewareを追加しました。

27
meder omuraliev

後でこれに来た人にとっては、Django-strongholdがあなたのユースケースによく合っていることに気付くかもしれません。公開したいURLをホワイトリストに登録し、残りはログインが必要です。

https://github.com/mgrouchy/Django-stronghold

13
Justin Abrahms

これは少し短いミドルウェアです。

from Django.contrib.auth.decorators import login_required

class LoginRequiredMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        if not getattr(view_func, 'login_required', True):
            return None
        return login_required(view_func)(request, *view_args, **view_kwargs)

以下を表示するためにログインする必要がない各ビューで、「login_required」をFalseに設定する必要があります。

関数ビュー:

def someview(request, *args, **kwargs):
    # body of view
someview.login_required = False

クラスベースのビュー:

class SomeView(View):
    login_required = False
    # body of view

#or

class SomeView(View):
    # body of view
someview = SomeView.as_view()
someview.login_required = False

これは、ログインビューについて何かをする必要があることを意味しますが、とにかく私はいつも自分のauth-backendを書くことになります。

8
kaleissin

以前の回答のいくつかは、時代遅れ(古いバージョンのDjango)であるか、不十分なプログラミング手法(URLをハードコーディングし、ルートを使用しない)を導入しています。これが私の見解ですDRYそして持続可能/維持可能( 上記のMehmetの答え から適応)。

ここでの改善点を強調するために、これはURLにルート名を付けることに依存しています(これは、変更されて末尾/先頭にスラッシュがあるハードコードされたURL/URIを使用するよりもはるかに信頼性があります)。

from Django.utils.deprecation import MiddlewareMixin
from Django.urls import resolve, reverse
from Django.http import HttpResponseRedirect
from my_project import settings

class LoginRequiredMiddleware(MiddlewareMixin):
    """
    Middleware that requires a user to be authenticated to view any page other
    than LOGIN_URL. Exemptions to this requirement can optionally be specified
    in settings by setting a Tuple of routes to ignore
    """
    def process_request(self, request):
        assert hasattr(request, 'user'), """
        The Login Required middleware needs to be after AuthenticationMiddleware.
        Also make sure to include the template context_processor:
        'Django.contrib.auth.context_processors.auth'."""

        if not request.user.is_authenticated:
            current_route_name = resolve(request.path_info).url_name

            if not current_route_name in settings.AUTH_EXEMPT_ROUTES:
                return HttpResponseRedirect(reverse(settings.AUTH_LOGIN_ROUTE))

そしてsettings.pyファイルでは、以下を定義できます。

AUTH_EXEMPT_ROUTES = ('register', 'login', 'forgot-password')
AUTH_LOGIN_ROUTE = 'register'
3
dKen

これがDjango 1.10+の古典的なLoginRequiredMiddleware

from Django.utils.deprecation import MiddlewareMixin

class LoginRequiredMiddleware(MiddlewareMixin):
    """
    Middleware that requires a user to be authenticated to view any page other
    than LOGIN_URL. Exemptions to this requirement can optionally be specified
    in settings via a list of regular expressions in LOGIN_EXEMPT_URLS (which
    you can copy from your urls.py).
    """
    def process_request(self, request):
        assert hasattr(request, 'user'), """
        The Login Required middleware needs to be after AuthenticationMiddleware.
        Also make sure to include the template context_processor:
        'Django.contrib.auth.context_processors.auth'."""
        if not request.user.is_authenticated:
            path = request.path_info.lstrip('/')
            if not any(m.match(path) for m in EXEMPT_URLS):
                return HttpResponseRedirect(settings.LOGIN_URL)

注目すべき違い:

  • path.to.LoginRequiredMiddlewareは、settings.pyのMIDDLEWARE_CLASSESではなくMIDDLEWAREに含める必要があります。
  • is_authenticatedはブール値でありメソッドではありません。
  • 詳細については、 docs を参照してください(一部の部分はあまり明確ではありませんが)。
3
mehmet

ミドルウェアを使用します。

http://www.djangobook.com/en/2.0/chapter17/ および http://docs.djangoproject.com/en/1.2/topics/http/middleware/#topics -http-ミドルウェア

これは1.2ではあまり変わらなかったと思います

ミドルウェアを使用すると、定義したとおりに、さまざまな時間/条件ですべての要求を処理するメソッドを使用してクラスを作成できます。

たとえば、process_request(request)はビューの前に起動し、この時点で認証と承認を強制できます。

2
andyortlieb

ビューがたくさんあり、どのビューにも触れたくない場合は、この問題にミドルウェアを使用できます。以下のコードを試してください。


import traceback
from Django.contrib.auth.decorators import login_required


class RejectAnonymousUsersMiddleware(object):

    def process_view(self, request, view_func, view_args, view_kwargs):
        current_route_name = resolve(request.path_info).url_name

        if current_route_name in settings.AUTH_EXEMPT_ROUTES:
            return

        if  request.user.is_authenticated:
            return

        return login_required(view_func)(request, *view_args, **view_kwargs)

注意:

  • このミドルウェアをsettings.pyのミドルウェアセクションの一番下に追加する必要があります
  • この変数をsettings.py に配置する必要があります
    • AUTH_EXEMPT_ROUTES =( 'register'、 'login'、 'forgot-password')
0
Ehsan Ahmadi

Djangoログインが必要なミドルウェア

このコードをmiddleware.pyに入れてください:

from Django.http import HttpResponseRedirect
from Django.conf import settings
from Django.utils.deprecation import MiddlewareMixin
from re import compile

EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
    EXEMPT_URLS += [compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]

class LoginRequiredMiddleware(MiddlewareMixin):
    def process_request(self, request):
        assert hasattr(request, 'user')
        if not request.user.is_authenticated:
            path = request.path_info.lstrip('/')
            if not any(m.match(path) for m in EXEMPT_URLS):
                return HttpResponseRedirect(settings.LOGIN_URL)

そして、settings.pyで:

LOGIN_URL = '/app_name/login'

LOGIN_EXEMPT_URLS=(
    r'/app_name/login/',
)

MIDDLEWARE_CLASSES = (
    # ...
    'python.path.to.LoginRequiredMiddleware',
)

このように: 'app_name.middleware.LoginRequiredMiddleware'

0
Aashish Mamgain

meder omuralievに加えて、次のような免除URLが必要な場合は回答してください(正規表現を使用):

url(r'^my/url/(?P<pk>[0-9]+)/$', views.my_view, name='my_url')

次のようにEXEMPT_URLSリストに追加します。

LOGIN_EXEMPT_URLS = [r'^my/url/([0-9]+)/$']

r '..'必要な文字列の先頭。

0
magrif