異なる場所からDjango Webアプリケーションへの複数のログインを検出するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/821870

  •  03-07-2019
  •  | 
  •  

質問

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

役に立ちましたか?

解決

これがまだ必要かどうかはわかりませんが、ソリューションを共有すると思いました:

1)django-trackingをインストールします(Van Gale Google Maps + GeoIPはすばらしいヒントです!)

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の後にあることを確認してください。新しいユーザーがログインすると、以前のログインが自動的にバンプされます:)

他のヒント

ここで提案されているように既に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 ルックアップに追加できます。

Djangoのミドルウェアがおそらく役立つでしょうあなたはこれを達成します。問題は、おそらく同じIPアドレスからの複数の匿名セッションを許可したいということです。異なるユーザーの認証セッションであっても、同じユーザーの認証セッションは許可しません。

次のことを行います:

  1. ユーザーの最後のログインのIPアドレスを保存するユーザープロファイルモデルを作成します。 Djangoのユーザーに関する追加情報の保存ドキュメント。

  2. カスタム認証バックエンド。このバックエンドは、トリガーされてユーザーを正常に認証すると(スーパーを呼び出すだけ)、プロファイルモデル内のユーザーの最後のログインIPを消去します。

  3. Djangoの django.contrib.sessions.SessionMiddleware クラスのサブクラスを実装します。 process_request を実装します。 request.user オブジェクトのプロファイルモデルにIPアドレスがない場合は、それを設定して要求を許可します。 IPがあり、そのIPが現在のリクエストのIP( request.META.REMOTE_ADDR )と異なる場合、他のユーザーをログアウトするか、エラーをリクエスタ。

  4. settings.py ファイルを更新して、カスタム認証バックエンドが最初に処理され、カスタムセッションミドルウェアも最初に処理されるようにします。これには、 settings.AUTHENTICATION_BACKENDS および settings.MIDDLEWARE_CLASSES の更新が含まれます。

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

ミドルウェアの 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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top