10

내 사이트는 장고로 작성된 디지털 마켓 웹 사이트입니다.장고에서 동일한 계정으로 로그인 한 동시 사용자 수를 제한하는 방법

사이트의 디지털 콘텐츠 (텍스트, 이미지, 동영상)는 기본적으로 '잠김'되어 있습니다. 해당 콘텐츠를 구입 한 사용자 만 볼 수 있습니다.

특정 사용자 (콘텐츠를 구매 한 사용자)가 많은 사람들 (예 : Facebook 그룹의 1,000 명 이상)에게 무료로 사용자 이름/비밀번호를 제공한다는 이야기가 있습니다. 그 1000 명의 사용자는 그 단일 사용자 이름/암호를 사용하여 로그인 한 다음 센트를 지불하지 않고 '잠긴'디지털 컨텐츠를 볼 수 있습니다.

동시 로그인 수를 동일한 계정으로 제한 할 수 있습니까?

내가이 패키지를 발견했습니다

https://github.com/pcraston/django-preventconcurrentlogins

하지만 그것이 무엇을하는 사람이 동일한 사용자 이름/비밀번호를 사용하여 로그인 할 때 밖으로 이전 사용자를 로그입니다. 그건 도움이 안된다. 왜냐하면 각 사용자는 '잠긴'콘텐츠에 액세스 할 때마다 매번 사용자 이름/암호를 입력하기 만하면되기 때문이다.

+0

https://github.com/ sobotklp/django-throttle-requests –

+0

안녕하세요. 감사. 나는 그것에 대해 들어 본 적이 없다. 그것을 들여다 보면 내 경우에 도움이되는지 알 수 있습니다. – Kakyoin

+0

안녕하세요. 나는 [documentation] (http://django-throttle-requests.readthedocs.io/en/latest/configuration.html)을 방문했다. 사용자 계정 당 요청 횟수를 제한하는 규칙이없는 것처럼 보인다. 공유 할 모범이 있습니까? 감사! – Kakyoin

답변

8

동시 사용자를 제한하려면 기존 sessions을 주시하십시오.

현재 접근 방식에서 사용자가 로그인하면 새 세션이 만들어집니다. 새 세션은 이전 세션과 공존하므로 동시 세션 수는 N입니다.

세션을 허용하려고합니다.

  • 같은에서 기존의 다른 세션을 제거, 각 로그인에
  • (이하 "user_logged_in"신호를 사용) 로그인 이벤트를 확장/감지 : 새 로그인이 발생하면 가장 쉬운 방법은 이전의 세션을 무효화하는 것 사용자 ("Clearing the session store" 참조)

기타 등등 ..., 이메일 확인을 필요로 로그인 이벤트를 조절, IP 당 차단, Two-factor authentication을 사용하는 것입니다 접근 (더 완벽하지만, 더 복잡한)

2

다른 모델에서 사용자 세션 매핑을 저장하십시오. 당신이 당신의 자신의 로그인보기가있는 경우

from django.conf import settings 
from django.contrib.sessions.models import Session 
from django.db import models 

class UserSessions(models.Model): 
    user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='user_sessions') 
    session = models.OneToOneField(Session, related_name='user_sessions', 
            on_delete=models.CASCADE) 

    def __str__(self): 
     return '%s - %s' % (self.user, self.session.session_key) 

, 당신은이 모델을 직접 업데이트 할 수 있습니다

from django.contrib.auth.views import login as auth_login 

def login(request): 
    auth_login(request) 
    if request.user.is_authenticated(): 
     session = Session.objects.get(session_key=request.session.session_key) 
     user_session = UserSession.objects.create(user=request.user, session=session) 
    no_of_logins = request.user.user_sessions.count() 
    if no_of_logins > 1: # whatever your limit is 
     request.SESSION['EXTRA_LOGIN'] = True 
     # Do your stuff here 

다른 옵션은 Signal을 사용하는 것입니다. Django는 신호를 제공합니다 : user_logged_in, user_login_faileduser_logged_out, Django 로그인보기를 사용하는 경우.

# signals.py 
from django.contrib.auth.signals import user_logged_in 
from django.dispatch import receiver 

@receiver(user_logged_in) 
def concurrent_logins(sender, **kwargs): 
    user = kwargs.get('user') 
    request = kwargs.get('request') 
    if user is not None and request is not None: 
     session = Session.objects.get(session_key=request.session.session_key) 
     UserSessions.objects.create(user=user, session=session) 
    if user is not None: 
     request.session['LOGIN_COUNT'] = user.user_sessions.count() 

# your login view 
def login(request): 
    auth_login(request) 
    if request.user.is_authenticated() and request.session['LOGIN_COUNT'] > 1: 
     # 'LOGIN_COUNT' populated by signal 
     request.session['EXTRA_LOGIN'] = True 
     # Do your stuff 

EXTRA_LOGIN 경우에는 이전 세션을 나열하고 로그 아웃 할 세션을 선택하도록 사용자에게 요청할 수 있습니다, True입니다.(다른 그가 잠겨 될 수있다, 로그인에서 그를 중단하지 마십시오 - 그는 지금 자신의 이전 세션에 대한 액세스 권한이없는 경우) 사용자에

3

1/프로파일들 응용 프로그램은 관리 명령 파일을 추가

https://docs.djangoproject.com/en/1.10/howto/custom-management-commands/

2 관리 명령 코드 : 더 다음 10 개 세션이 사용자의 모든 세션을 죽이고, 당신은 필요한 경우 1K로 그를 변경하거나이를 보낼 수 있습니다

는 다음이 가이드를 Managment를 명령을 추가하려면 값을 관리 명령의 매개 변수로 사용합니다.

from django.core.management.base import BaseCommand, CommandError 
from django.contrib.sessions.models import Session 
from django.contrib.auth.models import User 

class Command(BaseCommand): 
    def handle(self, *args, **options): 
     session_user_dict = {} 


     # users with more than 10 sessions - del all 

     for ses in Session.objects.all(): 
      data = ses.get_decoded() 
      user_owner = User.objects.filter(pk = data.get('_auth_user_id', None)) 

      if int(data.get('_auth_user_id', None)) in session_user_dict: 
       session_user_dict[int(data.get('_auth_user_id', None))] += 1 
      else: 
       session_user_dict[int(data.get('_auth_user_id', None))] = 1 

     for k,v in session_user_dict.iteritems(): 
      if v > 10: 
       for ses in Session.objects.all(): 
        data = ses.get_decoded() 
        if str(k) == data.get('_auth_user_id', None): 
         ses.delete() 

3 옵션 암호 변경 - 나쁜 사용자 세션을 살해 한 후 는 DIFF 하나에 잘못된 사용자 암호를 변경하고 헷갈. https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/

것은 당신이를 사용하는 경우 : 위의 코드에서 그 변화를 마지막 루프를 수행하려면

  for k,v in session_user_dict.iteritems(): 
      if v > 10: 
       for ses in Session.objects.all(): 
        data = ses.get_decoded() 
        if str(k) == data.get('_auth_user_id', None): 
         ses.delete() 
         theuser = User.objects.filter(pk=k) 
         #maybe use uuid to pick a password ... 
         theuser.set_password('new_unknown_password') 

4 분마다/시간이나 때마다 사용이 가이드를 crontab에하는 장고 관리 명령을 추가 virtual env, cron에서 실행되는 관리 명령은 virtual env에 먼저 입력해야한다는 것을 기억하십시오. 필요할 경우 도움을 요청하고 .sh 스크립트를 사용하여 수행 할 수 있습니다.