【问题标题】:django-channels: differentiate between different `AnonymousUser`sdjango-channels:区分不同的`AnonymousUser`
【发布时间】:2018-07-05 09:04:12
【问题描述】:

不幸的是,我正在使用 django-channels 频道 1.1.8,因为我错过了所有 频道 2.0 的更新。现在升级是不现实的,因为我们刚刚 启动,这需要一些时间才能正确计算出来。

这是我的问题:

我使用 *message.user.id * 来区分经过身份验证的 我需要向其发送消息的用户。但是,在某些情况下,我会 还需要向未经身份验证的用户发送消息 - 以及该消息 取决于外部 API 调用。我在 ws_connect() 中做到了这一点:

@channel_session_user_from_http
def ws_connect(message):
    # create group for user
    if str(message.user) == "AnonymousUser":
        user_group = "AnonymousUser" + str(uuid.uuid4())
    else:
        user_group = str(message.user.id)


    print(f"user group is {user_group}")
    Group(user_group).add(message.reply_channel)
    Group(user_group).send({"accept": True})
    message.channel_session['get_user'] = user_group

这只是问题的第一部分,基本上我是在随机附加一个 每个 AnonymousUser 实例的字符串。但是我找不到访问方法 此字符串来自请求对象中的一个视图,以便确定 我正在发送消息

这甚至可以实现吗?现在我无法访问任何设置 我认为的 ws_connect

编辑:按照 kagronick 的建议,我尝试了这个:

@channel_session_user_from_http
def ws_connect(message):
    # create group for user

    if str(message.user) == "AnonymousUser":
        user_group = "AnonymousUser" + str(uuid.uuid4())
    else:
        user_group = str(message.user.id)

    Group(user_group).add(message.reply_channel)
    Group(user_group).send({"accept": True})
    message.channel_session['get_user'] = user_group
    message.http_session['get_user'] = user_group
    print(message.http_session['get_user'])
    message.http_session.save()

但是,当用户是 AnonymousUser 时,http_sessionNone。其他装饰者没有帮助。

【问题讨论】:

    标签: django django-channels


    【解决方案1】:

    是的,您可以保存到会话并在视图中访问它。但是您需要使用 http_session 而不是通道会话。使用@http_session 装饰器或@channel_and_http_session。您可能需要调用 message.http_session.save() (我不记得了,我现在在 Channels 2 上。)。但在那之后,您将能够在视图中看到用户的组。

    此外,为此使用组有点过头了。如果该组只有 1 个用户,请将 reply_channel 放入会话中并在视图中执行类似 Channel(request.session['reply_channel']).send() 的操作。这样它就不需要查找组中的一个用户并且可以直接发送给用户。

    如果这解决了您的问题,请将其标记为已接受。

    【讨论】:

    • 正在在消费者上使用 http 会话,但仍然无法访问视图中的会话密钥。
    • 尝试调用 .save() 就可以了。
    • 您上面的代码正在使用通道会话。你能用你现在的代码更新你的代码吗?
    • message.http_session 在用户登录时有效,但在未登录时无效(返回 TypeError: 'NoneType' object does not support item assignment)。这很奇怪。我用于 ws_connect() 的装饰器是 @channel_session_user_from_http
    • 问题似乎是,对于所有装饰器,当用户未登录时,message.http_sessionNone
    【解决方案2】:

    编辑:不幸的是,这只适用于本地,但不适用于生产。当 AnonymousUser,message.http_sesssion 不存在时。

    用户kagronick 让我走上了正轨,他指出message 有一个http_session 属性。但是,当用户是 AnonymousUser 时,http_session 似乎总是 None in ws_connect,这违背了我们的目的。

    我通过检查用户是否是匿名的在视图中解决了这个问题,如果他是,这意味着他没有会话(或者至少频道看不到它),初始化一个,并将值 "AnonymousUser" + str(uuid.uuid4()) 分配给键 get_user(这种方式以前在消费者中完成)。

    在我这样做之后,每次调用ws_connect message 都会有一个http_session 属性:登录时的用户ID 或AnonymousUser-uuid.uuid4()

    【讨论】:

      猜你喜欢
      • 2016-07-06
      • 2020-08-03
      • 2013-05-10
      • 1970-01-01
      • 2018-01-12
      • 2017-12-02
      • 2017-01-02
      • 1970-01-01
      • 2020-11-06
      相关资源
      最近更新 更多