Apollo-client: Pluggable authentication in the network interface

Created on 30 Mar 2016  路  6Comments  路  Source: apollographql/apollo-client

After you log in to the server, you should be able to tell the client to send along a login token with every request.

This could also work as a feature to add a pluggable middleware to the network interface or client.

All 6 comments

A few notes:

  • [ ] the middleware can modify both the options passed to the request, and the headers by passing a compliant RequestInit object
  • [ ] we should document that the following fields are reserved body, headers.Accept, headers.Content-Type, method and probably warn if they are sent
  • [ ] the authentication middleware should only affect the headers. (Unless I'm missing another need?)

Since the network interface can be supplied to the client, I think having the middleware be attached to it makes the most sense. We could pretty easily return a way to apply middleware to the default network interface through the client object. public registerNetworkMiddleware seems a good enough solution

The question here is, if someone built an alternate network interface, would an existing login middleware work with it? It seems like the answer is probably no, because only an HTTP network interface would have a login middleware that uses headers. So it makes sense that it would be attached to the network interface I guess.

Everything you said sounds good then.

@stubailo @johnthepink and I talked through a few options for this. What are your thoughts on https://gist.github.com/jbaxleyiii/e899fe74842b7488657617e43c9a30fe

// the meat of the gist

const heighliner = createNetworkInterface('http://localhost:8888/');

interface MiddlewareRequest {
  request: Request;
  options: RequestInit;
}

// option 1, generic middleware that can modify the options of the request
const tokenMiddleware = (request: MiddlewareRequest, next: function): void => {
  // this would be called on each request and has the option to modify the headers
  // this doesn't return a value, but rather modifies the request inline.
  // that feels gross but I don't know of another way to do next() unless you pass
  // the request into next? which also seems odd
};

// option 2, authorization sugaring of option 1 that only modifies the headers
// and defaults to setting an 'Authorization' header.
heighliner.authorize('token': string, /* optional key name for token : string*/);
heighliner.removeAuthorization(/* probably just a null value here? */);


// the middleware would be on the networkInterface itself
// should this be an array? or allow for multiple arugments to be passed as args
// e.g. `use(middleware1, middleware2, etc)
heighliner.use(tokenMiddleware);

heighliner.authorize

is this better than something like:

const authMiddleware = new AuthTokenHeaderMiddleware(); 

heighliner.use([
  authMiddleware,
]);

authMiddleware.setToken(token);
authMiddleware.setToken(null);

Also, I think use should always take an array probably.

Other than that, looks really good! I think going with the express model where you modify the object is probably the best.

@stubailo that is what @johnthepink had too :+1: Let's go with that direction for the auth middleware

Closed via #75

Was this page helpful?
0 / 5 - 0 ratings