is_authenticated returns 对于已注销的用户为真

is_authenticated returns True for logged out user

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

然而,似乎用户对象的 is_authenticated() 方法 returns 为真,即使用户已经注销(调用 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

不幸的是,is_authenticated() 方法始终 returns 为真。

 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实例,也就是User没有通过认证时的设置。

您误解了 is_authenticated 正在检查的内容。

请记住,网络是一个无状态的环境。没有服务器级 'logged-in' 状态:用户是否登录的唯一记录是 cookie 是否存在于该用户的机器上。

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

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

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

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

Reference.