question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Accessing cookies in subscription resolver functions

See original GitHub issue

Hi, I’d like to quickly thank the contributors of this project for making graphql server creation so easy!

Here is my issue:

I am writing an API where an authentication cookie is sent along with the request. I am using the express cookie-parser middleware to parse the cookie and place it in request.cookies. This works fine for query and mutation resolver functions as I have access to the request object through the context argument of the resolver function. However, the express request object is not passed to subscription resolver functions (for a good reason I presume), meaning that I cannot access the cookie this way.

To my understanding, WebSocket requests are sent over HTTP, and from a little reading online, I think this means that WebSocket requests are able to access HTTP cookies.

If what I have said is correct, how can I access the cookies that are sent along with the request?

I have seen issue #393 with an accompanying PR #394. If this gets merged, could I access the cookies through the webSocket object passed into the context?

If so, could we get this PR merged (if there is nothing blocking it)? If cookies are able to be used with WebSockets, I think that it would be a great feature to add.

Here is the github link to the project that I am working on for reference: https://github.com/joealden/talq-api/.

It might also be worth mentioning that I have seen this https://www.apollographql.com/docs/react/advanced/subscriptions.html#authentication where you can send connectionParams with the request. But the issue is that because I am using a cookie that I want to be httpOnly, I cannot access it’s contents and send it as a connectionParam.

Please correct me if any of what I have said is wrong, and thanks for your time!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:17

github_iconTop GitHub Comments

3reactions
bakhaacommented, May 26, 2019

I solved this problem in the onConnect callback function.

const options = {
  cors: { credentials: true, origin },
  port: PORT,
  subscriptions: {
    onConnect: async (connectionParams, webSocket) => {
      try {
        const promise = new Promise((resolve, reject) => {
          session(webSocket.upgradeReq, {}, () => {
            resolve(webSocket.upgradeReq.session.passport);
          });
        });
        const user = await promise;
        return user;
      } catch (error) {
        console.log('error', error);
      }
    },
  },
};

Next, when you initialize the server, you can get the user in context.

const server = new GraphQLServer({
  typeDefs,
  resolvers,
  context: ({ request, connection }) => {
    let user = request ? request.user : null;
    if (connection) {
      if (connection.context.user) user = connection.context.user;
    }
    return { user, request, pubsub };
  },
});

An example can be found here https://github.com/bakhaa/pw/blob/master/api/app.js.

3reactions
joealdencommented, Aug 8, 2018

@captDaylight yeah sure, as I mentioned above, this is the repo that I am using it in: https://github.com/joealden/talq-api/ (it’s written in TypeScript).

https://github.com/joealden/talq-api/blob/92ef03bef75518e8e1cdb763f8890824af10e3a7/src/index.ts#L36: this is how I added the cookie-parser middleware. This means that I can now access the cookies sent with the request from the context arg in any query or mutation resolver function (if you named this arg context, through context.request.cookies).

https://github.com/joealden/talq-api/blob/92ef03bef75518e8e1cdb763f8890824af10e3a7/src/resolvers/utils.ts#L11: here I have a getUserId helper function that receives the context as an argument and checks if the jwt that is in the cookie is valid. Also in that same file I have a checkAuth function that I use when I need to know if the user is logged in but don’t need to use their user ID stored in the token cookie.

https://github.com/joealden/talq-api/blob/92ef03bef75518e8e1cdb763f8890824af10e3a7/src/resolvers/Query.ts#L5: then in the resolver functions, I use one of those above helper functions if I need to check if the user is logged in. If the user is logged in, the helper function will return and the resolver function will continue to execute, if the user is not logged in, the helper function will throw an error, causing the resolver function to halt execution and error out.

This code was inspired by @wesbos’s (unreleased) Advanced React codebase over at https://github.com/wesbos/Advanced-React. I altered the code to fit my use case. The helper function style code is inspired by this example code created by the @prismagraphql team: https://github.com/prismagraphql/prisma/blob/master/examples/authentication/src/utils.js#L6. I just altered how I retrieved the token because I wanted to use cookies instead of an Authorization HTTP header.

Thanks to Wes and the Prisma team for the great learning resources!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Accessing cookies in subscription resolver functions #424
I am using the express cookie-parser middleware to parse the cookie and place it in request.cookies. This works fine for query and mutation ......
Read more >
Cookie based user-filtering with Graphql Websocket ... - Medium
We use the utility function getCookie to fetch exactly what we need ... Lets see how we can define the subscription resolver as...
Read more >
How do I get cookie from apollo graphql resolver?
My graphql server is running at port 4000 and my nextjs client running at port 3000 . I can get client cookie with...
Read more >
Writing query resolvers | Full-Stack Quickstart - Apollo GraphQL
A resolver is a function that's responsible for populating the data for a single field in your schema. Whenever a client queries for...
Read more >
JavaScript resolver function reference for DynamoDB
The AWS AppSync DynamoDB function enables you to use GraphQL to store and retrieve data in existing Amazon DynamoDB tables in your account....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found