試圖通過一個非常簡單的websockets應用程序來獲取使用Django渠道的認證,該應用程序可以回傳用戶通過前綴"You said: "
發送的任何內容。使用Django渠道進行會話認證
我的流程:
web: gunicorn myproject.wsgi --log-file=- --pythonpath ./myproject
realtime: daphne myproject.asgi:channel_layer --port 9090 --bind 0.0.0.0 -v 2
reatime_worker: python manage.py runworker -v 2
我heroku local -e .env -p 8080
本地測試時運行的所有進程,但你也可以單獨運行它們。
請注意我有localhost:8080
上的WSGI和localhost:9090
上的ASGI。
路由和消費者:
### routing.py ###
from . import consumers
channel_routing = {
'websocket.connect': consumers.ws_connect,
'websocket.receive': consumers.ws_receive,
'websocket.disconnect': consumers.ws_disconnect,
}
和
### consumers.py ###
import traceback
from django.http import HttpResponse
from channels.handler import AsgiHandler
from channels import Group
from channels.sessions import channel_session
from channels.auth import channel_session_user, channel_session_user_from_http
from myproject import CustomLogger
logger = CustomLogger(__name__)
@channel_session_user_from_http
def ws_connect(message):
logger.info("ws_connect: %s" % message.user.email)
message.reply_channel.send({"accept": True})
message.channel_session['prefix'] = "You said"
# message.channel_session['django_user'] = message.user # tried doing this but it doesn't work...
@channel_session_user_from_http
def ws_receive(message, http_user=True):
try:
logger.info("1) User: %s" % message.user)
logger.info("2) Channel session fields: %s" % message.channel_session.__dict__)
logger.info("3) Anything at 'django_user' key? => %s" % (
'django_user' in message.channel_session,))
user = User.objects.get(pk=message.channel_session['_auth_user_id'])
logger.info(None, "4) ws_receive: %s" % user.email)
prefix = message.channel_session['prefix']
message.reply_channel.send({
'text' : "%s: %s" % (prefix, message['text']),
})
except Exception:
logger.info("ERROR: %s" % traceback.format_exc())
@channel_session_user_from_http
def ws_disconnect(message):
logger.info("ws_disconnect: %s" % message.__dict__)
message.reply_channel.send({
'text' : "%s" % "Sad to see you go :(",
})
再進行試驗,我進入的相同域作爲我的HTTP網站的Javascript控制檯,並鍵入:
> var socket = new WebSocket('ws://localhost:9090/')
> socket.onmessage = function(e) {console.log(e.data);}
> socket.send("Testing testing 123")
VM481:2 You said: Testing testing 123
而我的本地服務器日誌顯示:
ws_connect: [email protected]
1) User: AnonymousUser
2) Channel session fields: {'_SessionBase__session_key': 'chnb79d91b43c6c9e1ca9a29856e00ab', 'modified': False, '_session_cache': {u'prefix': u'You said', u'_auth_user_hash': u'ca4cf77d8158689b2b6febf569244198b70d5531', u'_auth_user_backend': u'django.contrib.auth.backends.ModelBackend', u'_auth_user_id': u'1'}, 'accessed': True, 'model': <class 'django.contrib.sessions.models.Session'>, 'serializer': <class 'django.core.signing.JSONSerializer'>}
3) Anything at 'django_user' key? => False
4) ws_receive: [email protected]
其中,當然,是沒有意義的。幾個問題:
- 爲什麼會Django的看到
message.user
作爲AnonymousUser
,但有實際的用戶ID_auth_user_id=1
(這是我正確的用戶ID)在會議? - 我在8080上運行本地服務器(WSGI),在9090(不同端口)上運行daphne(ASGI)。我的WebSocket連接中沒有包含
session_key=xxxx
- 但Django能夠正確讀取我的瀏覽器的cookie,[email protected]
? According to Channels docs, this shouldn't be possible。 - 在我的設置下,使用Django通道進行身份驗證的最佳/最簡單的方法是什麼?
嘗試這個 - 不會改變任何東西。我仍然收到完全相同的'AnonymousUser'對象。 – lollercoaster
使用'@ http_session_user'我可以得到正確的'message.user'對象,但是屬性'message.channel_session'不存在。 – lollercoaster