app.use(
"/graphql",
verifyUserToken,
graphqlExpress(req => {
return {
debug: true,
cacheControl: false,
tracing: false,
schema,
context: {
auth: req.auth,
settings: req.settings,
ip: req.ip,
...context
}
};
})
);
the context is undefined when SubscriptionServer tries to send back data and errors on the resolvers
There's a workaround by providing the onOperation option:
const subscriptionServer = SubscriptionServer.create(
{
schema,
execute,
subscribe,
onOperation: (message, params, webSocket) => {
return { ...params, context: { user: 'me' } }
},
},
{
server: websocketServer,
path: '/',
},
)
Thanks for the workaround, @schickling. But, is this really a workaround and not a solution? Is there/should there be another place where a context for each operation (a middleware) could be set?
I think that you can do it with onConnect:
new SubscriptionServer({
execute,
subscribe,
schema,
onConnect: (connectionParams, webSocket) => ({ user: 'me' }),
}, {
server: ws,
path: '/subscriptions',
});
But how to get req from here?
I think that it is indeed possible to set context in many onEvent properties. But, for example, with dataloaders one usually wants them to be created and passed as a context for each separate operation. This use case narrows possibilities to onOperation only, I guess?
Thanks for the feedback it cleared the context part but i have another issue
Well i'm finding out that the context passed on the express app is not sent by the websocket server which is correct
but the problem is the authentication token that i'm sending on the websocket is only received in this function on the SubscriptionServer
onConnect: async connectionParams => {
let [, USER_TOKEN] = connectionParams.authorization.split("Bearer ");
return {
auth: await context.api.getAuthInfo(USER_TOKEN)
};
},
but after on the onOperation method on the SubscriptionServer
onOperation: async (message, params, webSocket) => {
context.publish = publish;
context.pubsub = pubsub;
//context.auth = await context.api.getAuthInfo("");
context.settings = await context.api.getSettings();
params.context = { ...params.context, ...context };
return params;
}
context.auth is null when i try to console.log
any ideas where to get that auth token?
i'm doing this on the ApolloClient
const wsLink = new WebSocketLink({
uri: SUBSCRIPTIONS_ENDPOINT,
options: {
reconnect: true,
connectionParams: () => ({
authorization: getToken()
})
}
});
Just a thought as a wild guess: is third argument webSocket in onOperation the same for all connections or unique for each connection? If the latter is true, then I'd try to attach auth info to that somehow in onConnect.
Most helpful comment
There's a workaround by providing the
onOperationoption: