Como posso detectar vários logins em uma aplicação web Django partir de locais diferentes?

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

  •  03-07-2019
  •  | 
  •  

Pergunta

eu quero permitir que apenas uma sessão autenticada de cada vez para um login individual na minha aplicação Django. Portanto, se um usuário estiver conectado na página web em um determinado endereço IP, e essas mesmas credenciais de usuário são usadas para logon a partir de um endereço IP diferente, eu quero fazer algo (ou Sair o primeiro usuário ou negar acesso para o segundo usuário.)

Foi útil?

Solução

Não sei se isso ainda é necessária, mas pensei que eu iria partilhar a minha solução:

1) instalar o Django-tracking (obrigado por essa dica Van Gale Google Maps + GeoIP é incrível!)

2) Adicionar este middleware:

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) Certifique-se que vai atrás da VisitorTrackingMiddleware e você deve encontrar logins anteriores são automaticamente colidido quando alguém novos logs em:)

Outras dicas

Se você já está usando django-tracking como sugerido aqui, há uma maneira muito mais fácil de implementar esta:

Definir um manipulador de sinal:

# 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()

Criar um ouvinte para o sinal 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)

Isto irá instituir uma espécie de "último usuário a vitórias de login" do sistema. Se você quiser permitir que vários logins pelo mesmo usuário do mesmo IP, você pode adicionar um .exclude() para a pesquisa Visitors.

Django middleware provavelmente ajuda -lo a conseguir isso. A questão é que você provavelmente vai querer permitir que várias sessões anônimas do mesmo endereço IP, até mesmo sessões autenticadas para diferentes usuários, mas não autenticado sessões para o mesmo usuário.

Você vai querer:

  1. Criar um modelo de perfil de usuário para armazenar o endereço IP do último login de um usuário. Armazenando informações adicionais See de Django sobre usuários documentação.

  2. Implementar um autenticação personalizada backend . Este backend, quando acionado e autenticar com sucesso um usuário (apenas chamar super) eliminaria IP último login do usuário no modelo de perfil.

  3. Implementar uma subclasse da classe django.contrib.sessions.SessionMiddleware do Django. Implementar process_request. Se o modelo do perfil do objeto request.user não tem endereço IP, configurá-lo e permitir que a solicitação. Se ele tiver um IP eo IP é diferente do atual solicitação IP (request.META.REMOTE_ADDR), em seguida, fazer o que quiser, quer fazer logout do outro usuário, ou retornar um erro para o solicitante.

  4. Atualize seu arquivo settings.py para que seu backend auth personalizada é processada em primeiro lugar, e para que o seu middleware de sessão personalizado também é processado em primeiro lugar. Isso envolve a atualização settings.AUTHENTICATION_BACKENDS e settings.MIDDLEWARE_CLASSES.

Você vai precisar de fazer isso com middleware personalizado.

No seu método de process_request() middleware, você terá acesso ao objeto de solicitação para que você possa fazer algo como o seguinte:

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

Agora você sabe o endereço IP, de modo a verificar um modelo que você criar essa (aproximadamente) ficaria assim:

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

Assim, quando uma sessão é criado ou excluído você vai modifiy mesa do seu ip sessão em conformidade, e quando chega uma solicitação verifique se o endereço IP não está sendo usado por outra sessão. Se se é, em seguida, retornar um Http404 (ou algo parecido) do middleware.

Um aplicativo conectável que pode mostrar muito mais detalhes (e até mesmo inclui o endereço IP em seu próprio modelo) é django-tracking .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top