我将当前用户身份验证传递给应用程序中间软件,它工作得很好......但是当我在 GraphQL 中运行订阅时,它说找不到当前用户......我做错了什么,伙计们?当我从阿波罗服务器中删除当前用户时,它可以工作...我试图按照阿波罗网站上的文档来创建这个
我尝试将逻辑移动到阿波罗服务器的主体,但由于某种原因没有成功
const express = require('express');
const mongoose = require('mongoose');
const jwt = require('jsonwebtoken');
const cors = require('cors');
require('dotenv').config({ path: 'variables.env' });
const app = express();
const { createServer } = require('http');
const corsOptions = {
origin:'http://localhost:8000',
credentials:true
};
mongoose.set('useFindAndModify', false);
app.use(cors(corsOptions));
app.use(async (req , res , next) => {
const token = req.headers["authorization"];
if(token !== "null"){
try{
const currentUser = await jwt.verify(token, process.env.SECRET);
req.currentUser = currentUser;
console.log(currentUser)
}catch(err){
console.log(err)
}
}
next();
})
const Event = require('./models/Event');
const User = require('./models/User');
const Message = require('./models/Messages');
const { ApolloServer } = require('apollo-server-express');
const { typeDefs } = require('./Schema');
const { resolvers } = require('./Resolvers');
mongoose
.connect(process.env.MONGO_URI, {useNewUrlParser: true , useCreateIndex: true})
.then(() => console.log('DB connected'))
.catch(err => console.error(err))
const SERVER = new ApolloServer({
typeDefs,
resolvers,
context: ({req, res}) => ({
Event,
User,
Message,
currentUser:req.currentUser
}),
playground: {
settings: {
'editor.theme': 'dark'
}
}
});
SERVER.applyMiddleware({ app , path:'/graphql' });
const httpServer = createServer(app);
SERVER.installSubscriptionHandlers(httpServer);
const PORT = process.env.PORT || 5000;
httpServer.listen({ port: PORT }, () =>{
console.log(`🚀 Server ready at http://localhost:${PORT}${SERVER.graphqlPath}`)
console.log(`🚀 Subscriptions ready at ws://localhost:${PORT}${SERVER.subscriptionsPath}`)
})
在订阅的情况下,您使用的是 Web 套接字而不是常规的 http 请求,因此您的令牌在其他地方可用,即在 connection.context.Authorization
下(注意大写的"A"(,connection
由附加到 ApolloServer context
的函数提供,并在订阅上下文中定义。
您基本上希望将令牌验证移动到您的 ApolloServer 声明中:
const SERVER = new ApolloServer({
typeDefs,
resolvers,
context: ({req, connection}) => ({
Event,
User,
Message,
currentUser: async () => {
const token = connection
? connection.context.Authorization
: req.headers.authorization
return await jwt.verify(token, process.env.SECRET)
},
}),
...
这是一个非常简单的例子,你也可以检查req
是否存在,如果既没有设置connection
也没有设置req
,则生成错误,处理没有令牌的情况等,但你得到了基本的想法。
有关进一步参考,请参阅 Apollo Server 文档中的订阅上下文。