0

我正在使用 Django、Django REST 框架、Django-rest-auth 和 Django-allauth 编写服务器应用程序。我有一个用于在用户之间传递消息的方法,这应该只在接收者登录时发生。

然而,似乎用户对象的is_authenticated()方法返回 True 即使用户已经注销(调用rest-auth/logout/,这又应该调用 Django 的注销)。什么可能导致这种情况?我在这里错过了什么吗?

这是我的代码:

class SendMessage(generics.CreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = MessageSerializer

    def perform_create(self, serializer):
        m = self.request.data['msg']
        targetUser = User.objects.get(pk = self.request.data['user'])

        if targetUser.is_authenticated():
            # Send message
        else:
            # Don't send message
4

3 回答 3

6

不幸的是,is_authenticated() 方法总是返回 true。

 def is_authenticated(self):
    """
    Always return True. This is a way to tell if the user has been
    authenticated in templates.
    """
    return True

它旨在区分 User 实例和 AnonymousUser 实例,这是用户未通过身份验证时设置的内容。

于 2015-06-25T11:29:01.687 回答
1

尝试获取所有经过身份验证的用户,然后检查目标用户是否在其中:

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

def get_all_logged_in_users_ids():
    # Query all non-expired sessions
    # use timezone.now() instead of datetime.now() in latest versions of Django
    sessions = Session.objects.filter(expire_date__gte=timezone.now())
    uid_list = []

    # Build a list of user ids from that query
    for session in sessions:
        data = session.get_decoded()
        uid_list.append(data.get('_auth_user_id', None))
    return uid_list

class SendMessage(generics.CreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = MessageSerializer

    def perform_create(self, serializer):
        m = self.request.data['msg']
        if (self.request.data['user'] in get_all_logged_in_users_ids()):
            # Send message
        else:
            # Don't send message

参考

于 2015-06-25T13:42:52.410 回答
0

您误解了is_authenticated检查的内容。

请记住,Web 是一个无状态的环境。没有服务器级别的“登录”状态:用户是否登录的唯一记录是该 cookie 是否存在于该用户的机器上。

由于用户总是有可能在不通知服务器的情况下关闭浏览器或关闭机器,因此没有可靠的方法可以知道用户是否真正登录。您可以解决的唯一方法是每隔几秒钟就会有某种重复的 Ajax 调用,发布到一个用当前时间更新用户记录的视图。然后您可以检查用户是否确实在最后几秒钟内进行了更新。不过,这并不完全可靠。

或者,您可以考虑使用某种长轮询系统来保持通道打开。

于 2015-06-25T12:56:17.093 回答