如何从 consumer.py django 访问用户信息? [英] How to access user infos from consumer.py django?

查看:28
本文介绍了如何从 consumer.py django 访问用户信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 react.js 和 django、django-rest-framework、djoser, django-channels==3.0.2..好吧,问题是我想在朋友请求以及帖子和评论之类的情况下建立一个通知系统.问题是我想要某种安全性,当我通过 websocket 从 react 发送请求时,我想检查发送者是否是经过身份验证的用户,通过在 websockets 上发送用户 ID,并将其与登录的在用户的 id 中.由于我无法获得 self.scope['user'] 因为我使用 Djoser 进行身份验证,有没有其他方法可以实现这一点?

I am building a social media app with react.js and django, django-rest-framework, djoser, django-channels==3.0.2.. well the problem is i want to make a notification system on friend request and on like of post and comment. The problem is I want to have some kind of security that when I send a request through the websocket from react, I want to check if the sender is the authenticated user,by sending the user id on the websockets, and comparing it to the logged in user's id.Since I can't get the self.scope['user'] because i'm using Djoser for authentication, is there any other way to achieve this ?

推荐答案

您是否尝试过在您的 django-channels 应用中添加中间件来对用户进行身份验证和授权,如果不按照以下步骤操作:1)在与 routing.py 相同的文件夹中创建一个名为 middleware.py 的新文件2)在middleware.py中添加如下内容
注意:以下实现来自 django-channels 文档

Have you tried adding a middleware in your django-channels app to authenticate and authorize the user, if not follow these steps: 1)create a new file called middleware.py in the same folder as routing.py 2)add the following contents in the middleware.py
Note: The following implementation is from django-channels documentation

from urllib.parse import parse_qs

from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser
from django.db import close_old_connections
from channels.auth import AuthMiddleware, AuthMiddlewareStack, UserLazyObject
from channels.db import database_sync_to_async
from channels.sessions import CookieMiddleware, SessionMiddleware
from rest_framework_simplejwt.tokens import AccessToken

User = get_user_model()

"""[summary]
plucks the JWT access token from the query string and retrieves the associated user.
  Once the WebSocket connection is opened, all messages can be sent and received without
  verifying the user again. Closing the connection and opening it again 
  requires re-authorization.
for example: 
ws://localhost:8000/<route>/?token=<token_of_the_user>

"""


@database_sync_to_async
def get_user(scope):
    close_old_connections()
    query_string = parse_qs(scope['query_string'].decode())
    token = query_string.get('token')
    if not token:
        return AnonymousUser()
    try:
        access_token = AccessToken(token[0])
        user = User.objects.get(id=access_token['id'])
    except Exception as exception:
        return AnonymousUser()
    if not user.is_active:
        return AnonymousUser()
    return user


class TokenAuthMiddleware(AuthMiddleware):
    async def resolve_scope(self, scope):
        scope['user']._wrapped = await get_user(scope)


def TokenAuthMiddlewareStack(inner):
    return CookieMiddleware(SessionMiddleware(TokenAuthMiddleware(inner)))

3) 将中间件配置到路由中3.1)打开routing.py

3)configure the middleware into the routes 3.1)open routing.py

from channels.routing import ProtocolTypeRouter
from django.urls import path
from channels.routing import ProtocolTypeRouter, URLRouter
from <base-app-name>.middleware import TokenAuthMiddlewareStack

from <app-name>.consumers import <consumer-name>

application = ProtocolTypeRouter({
    'websocket': TokenAuthMiddlewareStack(
        URLRouter([
            path('<route>/', <consumer-name>),
        ]),
    ),
})

4)在AsyncWebSocketConsumer的connect方法中检查用户

4)check for user in connect method of AsyncWebSocketConsumer

async def connect(self):
    user = self.scope['user']
    if user.is_anonymous:
        await self.close()
    else:
        <your logic>

这篇关于如何从 consumer.py django 访问用户信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆