我正在使用 https://github.com/davidyaha/graphql-redis-subscriptions 中的“graphql-redis-subscriptions” 。 给出了有关如何设置订阅的几个示例,它们实际上有效,但我面临的问题是如何进行身份验证并允许订阅仅由登录的客户端用户收听。我使用 Apollo-server 来提供 graphql api,如下所示:
const server = new ApolloServer({
schema,
dataSources,
context: async ({ req, connection }) => {
if (connection) {
return {
...connection.context
};
}
const token = req.headers[API_TOKEN];
return {
premiumAuth: token
};
},
});
server.listen(5000);
请您参考如下方法:
在apollo-server
的context
选项中进行Authenticated用于HTTP协议(protocol)请求认证。这意味着它将保护 /graphql
端点免受未经身份验证的访问。例如
const contextFunction: ContextFunction<IContextFunctionParams, IConnectors<IMemoryDB>> = (
context: IContextFunctionParams,
): Context<IAppContext> => {
const { req, connection } = context;
if (connection) {
return connection.context;
} else {
const token: string = validateToken(req);
const userConnector = new UserConnector<IMemoryDB>(memoryDB);
let user: IUser | undefined;
try {
const userType: UserType = UserType[token];
user = userConnector.findUserByUserType(userType);
} catch (error) {
throw error;
}
return {
requestingUser: user,
locationConnector: new LocationConnector<IMemoryDB>(memoryDB),
userConnector,
templateConnector: new TemplateConnector<IMemoryDB>(
memoryDB,
pubsub,
// postgresPubSub,
),
};
}
};
用于WebSocket协议(protocol)连接,graphql订阅所依赖。 您需要在 subscriptions.onConnect
方法内进行身份验证,例如
const server = new ApolloServer({
typeDefs,
resolvers,
context: contextFunction,
introspection: true,
subscriptions: {
onConnect: (
connectionParams: IWebSocketConnectionParams,
webSocket: WebSocket,
connectionContext: ConnectionContext,
) => {
console.log('websocket connect');
console.log('connectionParams: ', connectionParams);
if (connectionParams.token) {
const token: string = validateToken(connectionParams.token);
const userConnector = new UserConnector<IMemoryDB>(memoryDB);
let user: IUser | undefined;
try {
const userType: UserType = UserType[token];
user = userConnector.findUserByUserType(userType);
} catch (error) {
throw error;
}
const context: ISubscriptionContext = {
// pubsub: postgresPubSub,
pubsub,
subscribeUser: user,
userConnector,
locationConnector: new LocationConnector<IMemoryDB>(memoryDB),
};
return context;
}
throw new Error('Missing auth token!');
},
onDisconnect: (webSocket: WebSocket, connectionContext: ConnectionContext) => {
console.log('websocket disconnect');
},
},
});
源代码:https://github.com/mrdulin/apollo-graphql-tutorial/tree/master/src/subscriptions