我的 Apollo 服务器的订阅不起作用:无法读取未定义的属性“标题”
Posted
技术标签:
【中文标题】我的 Apollo 服务器的订阅不起作用:无法读取未定义的属性“标题”【英文标题】:My Apollo Server's Subscription doesn't works: Cannot read property 'headers' of undefined 【发布时间】:2020-01-08 21:01:42 【问题描述】:我尝试将它与上下文连接一起使用,并将订阅参数添加到 Apollo 服务器中,但它不起作用。我是第一次使用 Apollo Server Subscriptions,我不知道错误是在服务器配置中还是在解析器中。 我在查询或变异方面没有问题,问题是订阅。
这是我的 index.js:
import express from 'express';
import createServer from 'http';
import ApolloServer from 'apollo-server-express';
import typeDefs from './data/schema';
import resolvers from './data/resolvers';
import cors from 'cors';
import jwt from 'jsonwebtoken';
const bodyParser = require('body-parser');
const PORT = process.env.PORT || 4004;
const app = express();
app.use(bodyParser.json());
app.use(cors());
const server = new ApolloServer(
typeDefs,
resolvers,
context: async(req, connection) =>
console.log("Context connection", connection)
const token = req.headers['authorization'];
if(connection)
return connection.context;
else
if(token !== "null")
try
//validate user in client.
const currentUser = await jwt.verify(token, process.env.SECRET);
//add user to request
req.currentUser = currentUser;
return
currentUser
catch(err)
return "";
,
subscriptions:
path: "/subscriptions",
onConnect: async (connectionParams, webSocket, context) =>
console.log(`Subscription client connected using Apollo server's built-in SubscriptionServer.`)
,
onDisconnect: async (webSocket, context) =>
console.log(`Subscription client disconnected.`)
);
server.applyMiddleware(app);
const httpServer = createServer(app);
server.installSubscriptionHandlers(httpServer);
httpServer.listen( port: PORT , () =>
console.log(`???? Server ready at
http://localhost:$PORT$server.graphqlPath`)
console.log(`???? Subscriptions ready at
ws://localhost:$PORT$server.subscriptionsPath`)
)
从游乐场
我的突变:
mutation
pushNotification(label:"My septh notification")
label
我的查询:
query
notifications
label
我的订阅:
subscription
newNotification
label
错误是:
"error":
"message": "Cannot read property 'headers' of undefined"
【问题讨论】:
【参考方案1】:我这样做就解决了:
const server = new ApolloServer(
typeDefs,
resolvers,
context: async ( req, connection ) =>
if (connection)
// check connection for metadata
return connection.context;
else
// check from req
const token = req.headers.authorization
if(token !== "null")
try
//validate user in client.
const currentUser = await jwt.verify(token, process.env.SECRET);
//add user to request
req.currentUser = currentUser;
return
currentUser
catch(err)
return "";
,
);
【讨论】:
【参考方案2】:问题是,在你的行中
const token = req.headers['authorization'];
对于 WebSocket 连接,变量 req
将未定义。认证请参考https://www.apollographql.com/docs/graphql-subscriptions/authentication/
【讨论】:
我阅读了文档,但我不知道如何使用 jwt 令牌来实现它。如果您有任何资源可以与我分享,我将不胜感激。谢谢【参考方案3】:上下文回调时可以查看jwt token
server = new ApolloServer(
schema: schema ,
graphiql: true ,
context:(req, connection )=>
if connection
token = connection.context["x-access-token"]
decoded = await LoginService.verify token #verify by jwt
if decoded == null
throw new Error("auth required")
return connection.context
headers = req.headers
token = headers["x-access-token"]
decoded = await LoginService.verify token #verify by jwt
return authed: decoded != null
)
【讨论】:
以上是关于我的 Apollo 服务器的订阅不起作用:无法读取未定义的属性“标题”的主要内容,如果未能解决你的问题,请参考以下文章
APOLLO CLIENT - 突变不起作用(无法读取未定义的属性“数据”)
Apollo 网关在 docker-compose 中不起作用