Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graphql remote schema stiching and cookies #969

Closed
1 of 5 tasks
mregula opened this issue Oct 8, 2018 · 5 comments
Closed
1 of 5 tasks

Graphql remote schema stiching and cookies #969

mregula opened this issue Oct 8, 2018 · 5 comments

Comments

@mregula
Copy link

mregula commented Oct 8, 2018

  • has-reproduction
  • feature
  • docs
  • blocking
  • good first issue

Hello,

I have two graphql endpoints (authentiaction endpoint [AUTH] and application endpoint [APP]).
I created the api gateway using "makeRemoteExecutableSchema" and "introspectSchema".

The thing is that [AUTH] endpoint in login mutation returns a cookie:

res.cookie("token", token, {
  httpOnly: true,
  secure: process.env.NODE_ENV === "production",
  maxAge: 1000 * 60 * 60 * 24 * 7 // 7 days
  // maxAge: null // Session cookie (when user closes browser it's ereased)
});

The thing is, when I make a request directly to the [AUTH] endpoint, the cookie is set (I can see "Set-cookie" resposne headers). But when I make a login mutation via API gateway, the cookie is not set. How to solve my issue?

@ghost ghost added the good first issue label Oct 8, 2018
@stefanoruth
Copy link

Having same issue, did you solve it?

@tunurgitr
Copy link

tunurgitr commented Feb 26, 2019

I had a similar issue that I resolved by wiring up a custom ApolloLink and a custom GraphQLExtension: https://spectrum.chat/apollo/apollo-server/makeremoteexecutableschema-and-response-cookies~3da601de-f533-45a4-9928-d1ff08c68c84?m=MTU1MTIxMDM4OTIxMQ==

Here's the text from that post:


First, I created a custom ApolloLink to take response headers and add them to the graphqlContext as responseHeaders. This gets concatenated to the beginning of the link chain:

const wrappingLink = new ApolloLink((operation, forward) => {
  return forward(operation).map(response => {
    const context = operation.getContext();
    if (!context.graphqlContext.responseHeaders) {
      context.graphqlContext.responseHeaders = new Headers();
    }
    if (context.response.headers) {
      context.response.headers.forEach((value, key) => {
        context.graphqlContext.responseHeaders.append(key, value)
        console.log(`gathering remote header: ${key}:${value}`)
      })
    }
    return response;
  })
})

Then I created an GraphQLExtension that adds response headers for any values in the responseHeaders field in the graphqlContext

RemoteResponseHeaderExtensions.ts

import { GraphQLExtension, GraphQLResponse } from 'graphql-extensions';

export class RemoteResponseHeaderExtensions<TContext = any> extends GraphQLExtension {

  public constructor(
  ) {
    super();
  }

  public willSendResponse(o: {
    graphqlResponse: GraphQLResponse;
    context: TContext;
  }): void | { graphqlResponse: GraphQLResponse; context: TContext } {
    console.log('running response middleware')
    console.log('response headers: ', o.context.responseHeaders)
    if (o.context.responseHeaders) {
      o.context.responseHeaders.forEach((value, key) => {
        if (key === 'set-cookie') {
          o.graphqlResponse.http.headers.append(key, value)
        }
      })
    }
    // o.graphqlResponse.http.headers.append()
    o.graphqlResponse.http.headers.forEach((value, key) => {
      console.log(`headers to append: "${key}: ${value}"`)
    })
    return {
      ...o,
      graphqlResponse: {
        ...o.graphqlResponse,
        gotProcessed: true
      }
    }
  }
}

These two work together to effectively proxy the set-cookie response header from the remote endpoint back to the client.

@mregula
Copy link
Author

mregula commented Mar 8, 2019

Wow...thanks a lot!

@stefanoruth
Copy link

Have not tested it yet but looks promising, will post results when had the time do implement it :)

@yaacovCR
Copy link
Collaborator

Closing. Above solution is server specific, specific to Apollo, although seeing as response headers are a server construction, that is to be expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants