Postgraphile: How to authorize subscriptions?

Created on 25 Mar 2019  ·  8Comments  ·  Source: graphile/postgraphile

I'm submitting a ...

  • [ ] bug report
  • [ ] feature request
  • [x] question

PostGraphile version: 4.4.0-beta.4

The normal approach for authorization in Postgraphile relies on setting the Authorization header from the client. But with WebSockets Javascript browser API this is not possible. I tried to see if a cookies approach is also available in Postgraphile to get around this. The closest I found is this:

https://github.com/graphile/postgraphile/issues/501

Is this the right starting point for trying to implement a cookie-based alternative to Authorization headers? And is that the right way to go in getting authorization to work with subscriptions in Postgraphile? Will I need to switch from using the CLI to using middleware?

Any guidance appreciated, thanks.

❔ question

Most helpful comment

Yeah; you can do:

const wsLink = new WebSocketLink({
  uri: `ws://localhost:5000/`,
  options: {
    reconnect: true,
    connectionParams: {
        authorization: `Bearer ${user.authToken}`,
    },
  },
});

All 8 comments

You can send the jwtToken via the "initial payload" too; this is what Apollo does for example:

https://www.apollographql.com/docs/react/advanced/subscriptions.html#authentication

[semi-automated message] Thanks for your question; hopefully we're well on the way to helping you solve your issue. This doesn't currently seem to be a bug in the library so I'm going to close the issue, but please feel free to keep requesting help below and if it does turn out to be a bug we can definitely re-open it 👍

Thanks. I can see where this would be handled in the postrgaphile code:

https://github.com/graphile/postgraphile/blob/master/src/postgraphile/http/subscriptions.ts

Line 198:

request.headers.authorization = String(normalizedConnectionParams['authorization']);

So it would seem that instead of sending the JWT token in the connection payload as "authToken" (as described by the Apollo link you gave) I need to send the equivalent of the entire header (including "Bearer ") in the payload as "authorization". Does that sound about right?

I hope to have time to code this up and try it soon.

Yeah; you can do:

const wsLink = new WebSocketLink({
  uri: `ws://localhost:5000/`,
  options: {
    reconnect: true,
    connectionParams: {
        authorization: `Bearer ${user.authToken}`,
    },
  },
});

Many thanks Benjie.

Do I have to set anything in postgraphile to choose the role of the JWT payload?
JWT Auth with the Apollo client (HTTP) it works, but not over websockets.

const ws = new WebSocketLink({
   uri: environment.graphWsUrl,
   options: {
        reconnect: true,
        lazy: true,
        connectionParams: async () => {
          const token = await this.authService.getToken();
          return {
            headers: {
              authorization: token ? `Bearer ${token}` : ''
            }
          };
        }
    }
});

Sorry, I was out of my mind....
Now it works.

const ws = new WebSocketLink({
  uri: environment.graphWsUrl,
  options: {
    reconnect: true,
    lazy: true,
    connectionParams: async () => {
      const token = await this.authService.getToken();
      return {
        Authorization: token ? `Bearer ${token}` : ''
      };
    }
  }
});

Ah; I didn't spot that either!

Was this page helpful?
0 / 5 - 0 ratings