25

私は、すべて同じアプリを使用していますが、独自のテンプレートを使用して、いくつかの独立したサイトを強化する Django サイト フレームワークを構築しています。django.contrib.sitesフレームワークの Django ドキュメントで提案されているように、複数の設定ファイルを使用して一意の SITE_ID を設定することで、これを達成する予定です。

ただし、サイト A のユーザーがサイト B にログインできるようにしたくありません。syncdb によって作成されたユーザー テーブルを調べたところ、ユーザーを特定のサイトに制限する可能性のある列が表示されません。また、一方のサイトでユーザー「bob」を作成してから、シェルコマンドを使用して反対側のすべてのユーザーを一覧表示しようとしましたが、そこに bob が表示されます。

すべてのユーザーがそれぞれのサイトに制限されていることを確認するにはどうすればよいですか?

4

3 に答える 3

28

これを行うための最も互換性のある方法は、サイト モデルへの外部キーを含むユーザー プロファイル モデルを作成し、その FK の値に対して現在のサイトをチェックするカスタム認証バックエンドを作成することです。サンプルコード:

app/models.py でプロファイル モデルを定義します。

from django.db import models
from django.contrib.sites.models import Site
from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    site = models.ForeignKey(Site)

デフォルトのものから継承して、カスタム認証バックエンドを作成します。たとえば、app/auth_backend.py に記述します。

from django.contrib.auth.backends import ModelBackend
from django.contrib.sites.models import Site

class SiteBackend(ModelBackend):
    def authenticate(self, **credentials):
        user_or_none = super(SiteBackend, self).authenticate(**credentials)
        if user_or_none and user_or_none.userprofile.site != Site.objects.get_current():
            user_or_none = None
        return user_or_none

    def get_user(self, user_id):
        try:
            return User.objects.get(
                pk=user_id, userprofile__site=Site.objects.get_current())
        except User.DoesNotExist:
            return None

この認証バックエンドは、すべてのユーザーがプロファイルを持っていることを前提としています。ユーザーの作成/登録プロセスで常に作成されるようにする必要があります。

オーバーライドさauthenticateれたメソッドにより、ユーザーは正しいサイトにのみログインできるようになります。このget_userメソッドは、ユーザーのセッションに保存されている認証情報に基づいて、データベースからユーザーをフェッチする要求ごとに呼び出されます。私たちのオーバーライドは、ユーザーがサイト A にログインし、同じセッション Cookie を使用してサイト B への不正アクセスを取得できないようにします (後者のケースを処理する必要性を指摘してくれた Jan Wrobel に感謝します)。

于 2009-09-10T15:12:32.443 に答える
3

サイト ID を考慮した独自の承認および認証バックエンドをプラグインできます。

django ドキュメントの他の認証ソースと認証バックエンドのリファレンスを参照してください。

それに加えて、django ソースが古すぎる場合は、authenticate() または login() コードをいつでも自分で変更できます。結局のところ... それがオープンソースの素晴らしさの 1 つではありませんか。そうすることで、他のモジュールとの互換性に影響を与える可能性があることに注意してください。

お役に立てれば。

于 2009-09-10T09:09:02.443 に答える
-1

多くの人が Django のデフォルトの認証システムと特権について不満を持っていることを知っておく必要があります。これは、オブジェクトのインスタンスなど、オブジェクトのルールだけです。これは、コードを書かなければ不可能だということを意味します。

ただし、この目標を達成するのに役立つ承認フックがいくつかあります。たとえば、次のようになります。

そこを見てください: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py とクラスの許可について。

独自のパーミッションを追加して、それらのルールを定義できます (User と ContentType の ForeignKey があります)。

ただし2、モンキーパッチ/いくつかのメソッドの変更なしでは難しい場合があります。

于 2009-09-10T13:20:00.833 に答える