57 votes

Comment rechercher une session Django pour un utilisateur particulier?

Je suis en train d'écrire une application où je serai en accédant à la base de données de django et à partir d'une application autonome. Les deux besoin de faire de la session de vérification et que la session doit être la même pour tous les deux. Django a construit dans d'authentification et de session de vérification, qui est ce que j'utilise, maintenant j'ai besoin de comprendre comment réutiliser la même session pour mon application autonome.

Ma question est comment puis-je rechercher un session_key pour un utilisateur particulier?

À partir de ce qu'il semble il n'y a rien qui relie auth_user et django_session

31voto

michael Points 1041

J'ai trouvé cet extrait de code

 from django.contrib.sessions.models import Session
from django.contrib.auth.models import User

session_key = '8cae76c505f15432b48c8292a7dd0e54'

session = Session.objects.get(session_key=session_key)
uid = session.get_decoded().get('_auth_user_id')
user = User.objects.get(pk=uid)

print user.username, user.get_full_name(), user.email
 

ici http://scottbarnham.com/blog/2008/12/04/get-user-from-session-key-in-django/

Je ne l'ai pas encore vérifié, mais ça a l'air plutôt simple.

28voto

James Bennett Points 6318

C'est un peu délicat à faire, parce que pas chaque session est nécessairement associé à un utilisateur authentifié; Django session du framework prend en charge les sessions anonymes ainsi, et n'importe qui qui visite votre site aura une session, indépendamment de savoir si ils sont connectés.

Ceci est rendu plus difficile encore par le fait que la session de l'objet lui-même est sérialisé -- depuis Django a aucun moyen de savoir laquelle des données que vous souhaitez exactement magasin, il suffit simplement de sérialise le dictionnaire de données de session dans une chaîne de caractères (en utilisant Python standard "cornichon" module) et le fourre dans votre base de données.

Si vous avez la clé de session (qui sera envoyée par le navigateur de l'utilisateur comme la valeur du cookie "sessionid"), la façon la plus simple pour obtenir les données est tout simplement pour interroger la table de Session pour la session avec cette clé, qui retourne un objet de Session. Vous pouvez ensuite appeler que "de l'objet get_decoded()" méthode pour obtenir le dictionnaire de données de la session. Si vous n'êtes pas à l'aide de Django, vous pouvez regarder le code source (à l'django/contrib/sessions/models.py pour voir comment les données de la session est désérialisé.

Si vous avez l'id de l'utilisateur, cependant, vous aurez besoin de faire une boucle par tous les objets de Session, la désérialisation de chacun et à la recherche de celui qui a une clé nommée "_auth_user_id", et pour laquelle la valeur de cette clé est l'id de l'utilisateur.

25voto

Peter Rowell Points 12444

La modification de l' django_session tableau pour ajouter une explicite user_id peut rendre la vie beaucoup plus facile. En supposant que vous faire (ou quelque chose de similaire), voici quatre approches pour munging les choses à votre goût:

Fourche de l' djago.contrib.session code. Je sais, je sais, c'est une chose horrible à penser. Mais c'est seulement de 500 lignes, y compris tous les backends et moins les tests. C'est assez simple à pirater. C'est le meilleur itinéraire que si vous allez faire un peu de sérieux réaménagement des choses.

Si vous ne voulez pas à la fourchette, vous pouvez essayer de vous connecter à l' Session.post_save de signal et munge là.

Ou vous pourriez MonkeyPatch contrib.session.models.Session.save(). Juste envelopper la méthode existante (ou en créer un nouveau), ateliers/synthétiser quelles que soient les valeurs que vous avez besoin, de les stocker dans votre nouveau champs, puis super(Session, self).save().

Encore une autre façon de le faire est de mettre dans les 2 (oui, deux) middleware les classes -- un avant et un après SessionMiddleware dans votre settings.py fichier. C'est à cause de la façon dont le middleware est traitée. L'un de ceux énumérés après SessionMiddleware obtiendrez, sur la requête entrante, une demande auprès de la session déjà attaché à elle. Une cité avant de faire une quelconque traitement de la réponse et/ou de modifier la/ré-enregistrer la session.

Nous avons utilisé une variante de cette dernière technique pour créer des pseudo-des séances pour les spiders des moteurs de recherche afin de leur donner un accès spécial à la matière qui est normalement réservées aux membres. Nous avons également de détecter des liens entrants, où l' REFERER champ est de l'associated moteur de recherche, et de nous donner à l'utilisateur un accès complet à un article.

7voto

Joe Points 41

Peter Rowell, merci pour votre réponse. Il fut d'une grande aide. C'est ce que j'ai fait pour le faire fonctionner. N'avait qu'à modifier un fichier dans djang.contrib.les sessions.

Dans django/contrib/sessions/models.py, ajouter le user_id à la table (à ajouter dans la table DB manuellement ou drop table et exécuter manage.py syncdb).

class Session(models.Model):

    ...

    user_id = models.IntegerField(_('user_id'), null=True)

    ...

    def save(self, *args, **kwargs):
        user_id = self.get_decoded().get('_auth_user_id')
        if ( user_id != None ):
            self.user_id = user_id

        # Call the "real" save() method.
        super(Session, self).save(*args, **kwargs)

Maintenant, à votre avis où vous faites la connexion (si vous utilisez de django reinhardt, de la base de la connexion, vous aurez à le remplacer)

# On login, destroy all prev sessions
        # This disallows multiple logins from different browsers
        dbSessions = Session.objects.filter( user_id = request.user.id )
        for index, dbSession in enumerate( dbSessions ):
            if ( dbSession.session_key != request.session.session_key ):
                dbSession.delete()

Cela a fonctionné pour moi.

6voto

hwjp Points 3041

J'ai couru à travers ce problème quand j'ai voulu lancer un spammeur. Il semble que la fixation de leur compte aux "inactifs" n'est pas assez, parce qu'ils peuvent encore venir sur leur session précédente. Alors - comment supprimer une session pour un utilisateur spécifique, ou de façon délibérée d'expiration d'une session pour un utilisateur spécifique?

La réponse est à l'utilisateur l' last_login le terrain pour traquer l'heure à laquelle la session a été désactivé, ce qui vous indique que l' expire_date est deux semaines plus tard, ce qui vous permet d'effectuer un filtre utile sur la table des sessions:

from django.contrib.sessions.models import Session
from django.contrib.auth.models import User
from datetime import datetime
from dateutil.relativedelta import relativedelta

baduser = User.objects.get(username="whoever")     
two_weeks = relativedelta(weeks=2)
two_hours = relativedelta(hours=2)
expiry = baduser.last_login + two_weeks
sessions = Session.objects.filter(expire_date__gt=expiry - two_hours,expire_date__lt=expiry + two_hours) 
print sessions.count() # there should only be one or two

for s in sessions:
    if s.get_decoded().get('_auth_user_id')==baduser.id:
        s.delete()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X