我的 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 - 突变不起作用(无法读取未定义的属性“数据”)

订阅在 React Native 中不起作用?

Apollo 客户端:cache.modify 不起作用?

Apollo 网关在 docker-compose 中不起作用

如何在 jest / apollo 客户端中捕获被拒绝的 graphql 订阅?

Apollo 客户端持久缓存不起作用