sending current user with channels websocket

I’m using django channels, and I’d like to be able to send the current user with sent messages. However, doing something like having <input type="hidden" id="userId" value="{{user.id}}"> doesn’t sit well with me for security reasons. Could someone not just inspect their page and swap out the id for another user’s, assuming they had access to it? What other way might I do this?

Here’s my room.html body (which is planned for further development, this is just a minimally edited snippet from channel’s tutorial):

<body>
    <textarea id="chat-log" cols="100" rows="20" readonly></textarea><br>
    <input id="chat-message-input" type="text" size="100"><br>
    <input id="chat-message-submit" type="button" value="Send">
    {{ room_name|json_script:"room-name" }}
    <script>
        const roomName = JSON.parse(document.getElementById('room-name').textContent);
        var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
        const chatSocket = new WebSocket(ws_scheme + '://' + window.location.host + '/ws/chat/' + roomName + '/');

        chatSocket.onmessage = function(e) {
            const data = JSON.parse(e.data);
            document.querySelector('#chat-log').value += (data.message + '\n');
        };

        chatSocket.onclose = function(e) {
            console.error('Chat socket closed unexpectedly');
        };

        document.querySelector('#chat-message-input').focus();
        document.querySelector('#chat-message-input').onkeyup = function(e) {
            if (e.keyCode === 13) {  // enter, return
                document.querySelector('#chat-message-submit').click();
            }
        };

        document.querySelector('#chat-message-submit').onclick = function(e) {
            const messageInputDom = document.querySelector('#chat-message-input');
            const message = messageInputDom.value;
            chatSocket.send(JSON.stringify({
                'message': message
            }));
            messageInputDom.value = '';
        };
    </script>
</body>

You don’t need to send it. The scope object, available in the consumer, contains the user object if you’ve got Authentication enabled.

Ken

1 Like

Thanks! Just found that out by reading deeper into the docs, which admittedly I should have done in the first place :sweat_smile:
I’m not used to good documentation :joy:
Link for people who may find this in the future: https://channels.readthedocs.io/en/latest/topics/authentication.html

hello i have the same problem from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application
import api.routing
from api.routing import websocket_urlpatterns

os.environ.setdefault(“DJANGO_SETTINGS_MODULE”, “mysite.settings”)

Initialize Django ASGI application early to ensure the AppRegistry

is populated before importing code that may import ORM models.

django_asgi_app = get_asgi_application()

application = ProtocolTypeRouter(
{
“http”: django_asgi_app,
“websocket”: AllowedHostsOriginValidator(
AuthMiddlewareStack(URLRouter(websocket_urlpatterns))
),
}
) thats my asgi conf the app is being served using react in the frontend but when i try to access self.scope[‘user’] it gives me keyerror no ‘user’

You are adding to a thread that is now more than three years old.

I suggest you open a new topic for your issue.

Also, when you post your code here, enclose the code between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```. This forces the forum software to keep your code properly formatted.

Finally, when you’re creating your new post, include a description of how you’re doing your authentication, and identify when you are opening the websocket relative to when you’re authenticating the user.