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

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 に答える