我将currentuser auth传递给应用middlware,它的工作原理还不错...但是当我在graphql中运行订阅时,它说当前用户未找到....我在做什么错人?当我从阿波罗服务器中删除currentuser时,它起作用了...我试图遵循阿波罗网站上的文档来创建它
我曾尝试将逻辑转移到apollo服务器的主体上,但由于某些原因未能解决
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}`)
})
答案 0 :(得分:0)
对于订阅,您使用的是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文档中的Context with Subscriptions,以获取更多参考。