适用于django1 -django2
django3可以参考:django3 channels 认证
在项目中想在websocket中加入认证
我是把 JWTtoken 加到了url 后面 ?之后 例如
var socket = new WebSocket('ws://'+window.location.host +'/wx/role/2/?eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjozOCwidXNlcm5hbWUiOiJobGx5em1zIiwiZXhwIjoxNTkwMjEyMDc1LCJlbWFpbCI6ImhAMTIzLmNvbSJ9.Zrh07IUmk5nJ3hXFHnNac6t5ai4Z7e2hQWS4WFpgLVI');
自己写的认证 ws_authentication.py
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser
from django.db import close_old_connections
from rest_framework_jwt.authentication import jwt_decode_handler
class QueryAuthMiddleware:
def __init__(self, inner):
self.inner = inner
def __call__(self, scope):
close_old_connections()
# User = get_user_model()
# user = User.objects.first()
token = scope["query_string"]
print(token)
token = token.decode("utf-8")
user = AnonymousUser()
if token:
user = authenticate(token)
print("*****")
return self.inner(dict(scope, user=user))
def authenticate(jwt_value):
try:
payload = jwt_decode_handler(jwt_value)
except Exception:
user = AnonymousUser()
print("-----------")
return user
user = authenticate_credentials(payload)
return user
def authenticate_credentials(payload):
username = payload.get('username')
try:
User = get_user_model()
user = User.objects.get(username=username)
except Exception:
user= AnonymousUser()
return user
使用上面的认证
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter, ChannelNameRouter
from django.contrib.auth.models import AnonymousUser
import users.routing
from users import consumers
from .ws_authentication import QueryAuthMiddleware
application = ProtocolTypeRouter({
# (http->django views is added by default)
'websocket': QueryAuthMiddleware(
URLRouter(
users.routing.websocket_urlpatterns
)
),
"channel": ChannelNameRouter({
"service-detection": consumers.ServiceConsumer,
}),
})