3๐
โ
I managed to get the token in the consumer payload and inject the user into the context.
from tinga.schema import schema
import channels_graphql_ws
from channels.db import database_sync_to_async
from django.contrib.auth.models import AnonymousUser
from graphql_jwt.utils import jwt_decode
from core.models import User
from channels_graphql_ws.scope_as_context import ScopeAsContext
@database_sync_to_async
def get_user(email):
try:
user = User.objects.get(email=email)
return user
except User.DoesNotExist:
return AnonymousUser()
class MyGraphqlWsConsumer(channels_graphql_ws.GraphqlWsConsumer):
"""Channels WebSocket consumer which provides GraphQL API."""
schema = schema
# Uncomment to send keepalive message every 42 seconds.
# send_keepalive_every = 42
# Uncomment to process requests sequentially (useful for tests).
# strict_ordering = True
async def on_connect(self, payload):
"""New client connection handler."""
# You can `raise` from here to reject the connection.
print("New client connected!")
# Create object-like context (like in `Query` or `Mutation`)
# from the dict-like one provided by the Channels.
context = ScopeAsContext(self.scope)
if 'token' in payload:
# Decode the token
decoded_data = jwt_decode(payload['token'])
# Inject the user
context.user = await get_user(email=decoded_data['email'])
else:
context.user = AnonymousUser
And then passing the token in the connectionParams
const wsLink = new WebSocketLink({
uri: process.env.VUE_APP_WS_GRAPHQL_URL || "ws://0.0.0.0:8000/ws/graphql/",
options: {
reconnect: true,
connectionParams: async () => {
const { value: authStr } = await Storage.get({ key: "auth" });
let token;
if (authStr) {
const auth = JSON.parse(authStr);
token = auth.token;
console.log(token); // So far so good the token is logged.
return {
token: token,
};
}
return {};
},
},
});
๐คBrieuc
Source:stackexchange.com