28

Django アプリケーションでの個々のログインに対して、一度に 1 つの認証済みセッションのみを許可したいと考えています。したがって、ユーザーが特定の IP アドレスで Web ページにログインし、同じユーザー資格情報を使用して別の IP アドレスからログインする場合、何かをしたい (最初のユーザーをログアウトするか、2 番目のユーザーへのアクセスを拒否する)。

4

4 に答える 4

22

これがまだ必要かどうかはわかりませんが、解決策を共有すると思いました:

1) django-tracking をインストールします。

2) 次のミドルウェアを追加します。

from django.contrib.sessions.models import Session
from tracking.models import Visitor
from datetime import datetime

class UserRestrictMiddleware(object):
    """
    Prevents more than one user logging in at once from two different IPs
    """
    def process_request(self, request):
        ip_address = request.META.get('REMOTE_ADDR','')
        try:
            last_login = request.user.last_login
        except:
            last_login = 0
        if unicode(last_login)==unicode(datetime.now())[:19]:
            previous_visitors = Visitor.objects.filter(user=request.user).exclude(ip_address=ip_address)
            for visitor in previous_visitors:
                Session.objects.filter(session_key=visitor.session_key).delete()
                visitor.user = None
                visitor.save()

3) それが VisitorTrackingMiddleware の後にあることを確認すると、誰かが新しいログインを行うと、以前のログインが自動的にバンプされることがわかります:)

于 2009-06-26T13:05:50.250 に答える
10

ここで提案されているように、すでに django-tracking を使用している場合は、これを実装するためのはるかに簡単な方法があります。

シグナル ハンドラーを定義します。

# myapp/signals.py
def kick_my_other_sessions(sender, request=None, user=None, **kwargs):
    from tracking.models import Visitor
    from django.contrib.sessions.models import Session
    keys = [v.session_key for v in Visitor.objects.filter(user=request.user).exclude(session_key=request.session.session_key)]
    Session.objects.filter(session_key__in=keys).delete()

user_logged_in シグナルのリスナーを作成します。

# myapp/__init__.py
from myapp.signals import kick_my_other_sessions
from django.contrib.auth.signals import user_logged_in
user_logged_in.connect(kick_my_other_sessions, sender=User)

これにより、一種の「最後にログインしたユーザーが勝つ」システムが導入されます。同じ IP からの同じユーザーによる複数のログインを許可する場合は.exclude()Visitorsルックアップに を追加できます。

于 2012-03-01T16:32:49.180 に答える
6

カスタムミドルウェアでこれを行う必要があります。

ミドルウェアprocess_request()メソッドでは、リクエスト オブジェクトにアクセスできるため、次のようなことができます。

session_key = request.session.session_key
ip_address = request.META.get('REMOTE_ADDR', '')

これで IP アドレスがわかったので、(おおまかに) 次のようなモデルを作成して確認してください。

class SessionIPS(models.Model):
    session = models.ForeignKey(Session)
    IP = models.CharField(max_length=20)

したがって、セッションが作成または削除されると、それに応じてセッション IP のテーブルを変更し、リクエストが届いたときに、その IP アドレスが別のセッションで使用されていないことを確認します。ある場合は、ミドルウェアから Http404 (またはそれに似たもの) を返します。

より多くの詳細を表示できる (さらに独自のモデルに IP アドレスを含む) プラグイン可能なアプリはdjango-trackingです。

于 2009-05-04T23:39:09.973 に答える