7

Django Web サイトと MyBB フォーラムがあり、それらの間で認証を共有したいと考えています。私のウェブサイトはかつて掲示板でした。次に、Django でいくつかのセクションを作成し、MyBB と Django の両方を同じドメインで実行しました。(フォーラムで) 登録すると、すべてのユーザーが Django ユーザーと MyBB ユーザーの 2 人のユーザーを取得するシステムをセットアップしました。ユーザーはフォーラムを使用してログインするため、Django で MyBB の Cookie を読み取り、対応する Django アカウントをログイン ユーザーとして設定する必要があります。

ミドルウェアでそれを行うことはできますか?このミドルウェアは MyBB の Cookie (MyBB ユーザーの ID を含む) を読み取りrequest.user、対応する Django ユーザーに設定します。私は Django を初めて使用し、ミドルウェアで設定request.user(または呼び出しauthenticate) することが良い考えかどうか (またはそれを行うためのより良い方法があるかどうか) がわかりません。

4

4 に答える 4

9

MyBB cookieに保存されているuser_idがDjangoデータベース内の同じユーザーを表す場合、デフォルトのDjangoバックエンドを使用してそのIDから直接ユーザーオブジェクトを取得できます。これらのIDが一致しない場合は、Djangoユーザーオブジェクトを取得するためのカスタムバックエンドが必要です。MyBB CookieからユーザーIDを取得し、それに基づいてユーザーを更新するには、カスタム認証ミドルウェアが必要です。

ミドルウェア

主なアイデアは、(認証ロジックに基づいて)ユーザーオブジェクトをフェッチし、それをrequest.userに割り当てることです。これが1つの例です(テストされていません)。

from django.contrib import auth

class MyBBMiddleware:
    def process_request(self, request):
        user_cookie_name = "session_key"
        if user_cookie_name not in request.COOKIES:
            # log user out if you want
            return 
        id = request.COOKIES.get(user_cookie_name)
        # this will find the right backend
        user = auth.authenticate(id) 
        request.user = user
        # if you want to persist this user with Django cookie do the following
        #auth.login(request, user)

これは、Djangoサイトに送信されるすべてのリクエストに対して呼び出されることに注意してください。パフォーマンスのために、ユーザーをキャッシュしたり、怠惰なオブジェクトのトリックを実行したりできます() 。

バックエンド

ユーザーオブジェクトをフェッチしてユーザーを認証するための独自のロジックを作成する必要がある場合は、次のようにすることができます。

class MyBBCookieBackend(object):
    def authenticate(self, user_id):
        return self.get_user(user_id)
    def get_user(self, user_id):
        # if user_id is not the same in Django and MyBB tables, 
        #  you need some logic to relate them and fetch Django user
        try:
            #TODO your custom logic
            user = User.objects.get(id=user_id)
            return user
        except User.DoesNotExist:
            return None

カスタムバックエンドとミドルウェアをサイト設定ファイルに追加する必要があります。

于 2012-11-15T23:18:19.253 に答える
5

ミドルウェアとDjango 認証バックエンドの組み合わせが正しいと思います。

ミドルウェアはauthenticate()、おそらくユーザー ID をキーワード引数としてバックエンドを呼び出します。次に、認証バックエンドが対応するメソッドを呼び出し、authenticate()ユーザー オブジェクトを返します。

class MiddlewareTracker:
 def process_request(self, request):
    id = request.COOKIES.get('logged_in_id') 
    authenticate(user_id = id)
    return None

class ForumAuthBackend(object):

    def authenticate(self, *args, **kwargs):
        id = kwargs.get('user_id')
        return User.objects.get(id = id)

    def get_user(self, user_id):
        return User.objects.get(id = user_id)

このhttps://docs.djangoproject.com/en/1.2/topics/auth/もお勧めします

于 2012-11-12T05:13:55.550 に答える
0

対処してみてください request.sessionrequestオブジェクトは、ビューの最初の引数として表示されます。ここでのセッションの詳細:https ://docs.djangoproject.com/en/dev/topics/http/sessions/

ミドルウェアで間違いなくそれを行うことができます:ミドルウェアの詳細については、https ://docs.djangoproject.com/en/dev/topics/http/middleware/を参照してください。

于 2012-11-12T00:54:57.320 に答える