2
votes

I need to work with Graphql development server which requires from user Basic authentication.

enter image description here On frontend side to make requests to protected graphql service I wrote next code

const authLink = setContext((_, { headers }) => {
   return {
      headers: {
         ...headers,
         Authorization: 'Basic ' + btoa('<login>:<pass>'),
      }
   }
});

const httpLink = new HttpLink({
   uri: process.env.REACT_APP_GQL_SERVER,
   fetchOptions: {
      mode: 'no-cors'
   }
});

const client = new ApolloClient({
   link: authLink.concat(httpLink),
   cache: new InMemoryCache(),
});

But I can't see "Authorization" header in the browser while request enter image description here

Could you please support me to paste Authorization header to the request or understand another way to work with Default Browser Authentication Prompt.

using: "apollo-boost": "^0.1.22", "apollo-link-context": "^1.0.12",

=============================================

Tested variant to put header #1

=============================================

const httpLink = createHttpLink({
   uri: process.env.REACT_APP_GQL_SERVER,
   fetchOptions: {
      mode: 'no-cors'
   },
});

const middlewareLink = new ApolloLink((operation, forward: any) => {
  operation.setContext({
    headers: {
      "Authorization": 'Basic ' + btoa('<login>:<password>')
    }
  });
  return forward(operation);
});

const client = new ApolloClient({
   link: middlewareLink.concat(httpLink),
   cache: new InMemoryCache(),
});

=============================================

Tested variant to put header #2

=============================================

const authLink = setContext((_, { headers }) => {
  return {
    headers: {
      ...headers,
      authorization: 'Basic ' + btoa('<login>:<password>'),
    }
  }
});

const httpLink = new HttpLink({
   uri: process.env.REACT_APP_GQL_SERVER,
   fetchOptions: {
      mode: 'no-cors'
   }
});

const links: any = [];
links.push(httpLink);
links.push(authLink);

const client = new ApolloClient({
   link: ApolloLink.from(links),
   cache: new InMemoryCache(),
});

=============================================

Tested variant to put header #3

=============================================

const middlewareLink = new ApolloLink((operation, forward: any) => {
  operation.setContext({
    headers: {
      authorization: 'Basic ' + btoa('<login>:<password>')
    }
  });
  return forward(operation);
});


const httpLink = new HttpLink({
   uri: process.env.REACT_APP_GQL_SERVER,
   fetchOptions: {
      mode: 'no-cors'
   }
});

const links: any = [];
links.push(httpLink);
links.push(middlewareLink);

const client = new ApolloClient({
   link: ApolloLink.from(links),
   cache: new InMemoryCache(),
});
1

1 Answers

1
votes

Shortness:

BAP - BROWSER AUTH PROMPT

Answer:

I worked around a lot and I found a solution:

  1. Add OPTIONS request as allowed on backend. Response for OPTIONS request should be always 200 or 2xx. We need to exclude OPTIONS request from BAP checking because by specification - OPTIONS request can't have 'Authorization' header, this header will be always removed from request and if BAP will check required 'Authorization' header in OPTIONS request ofcourse it will not be found.
  2. And I have created apollo-client in this way

    import gql from 'graphql-tag';
    import { ApolloClient, ApolloLink, HttpLink, InMemoryCache, FetchPolicy } from 'apollo-boost';
    import { onError } from 'apollo-link-error';
    
    const errorLink = onError(({ graphQLErrors, networkError }) => {
       if (graphQLErrors) {
          graphQLErrors.map(({ message, locations, path }) =>
             console.error(
                `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
             ),
          );
       }
       if (networkError) {
          logger.error(`[Network error]: ${networkError}`);
       }
    });
    
    const links: any = [];
    links.push(errorLink);
    links.push(
       new HttpLink({
          uri: process.env.REACT_APP_GQL_SERVER,
          headers: {
             authorization: 'Basic ' + btoa('<login>:<password>')
          },
       }),
    );
    
    const client = new ApolloClient({
       link: ApolloLink.from(links),
       cache: new InMemoryCache(),
    });
    
    1. BAP was enabled while no web-site auth was implemented. Of course, in production mode you will need to disable BAP and solution described here will cause another issues, so in future this solution should be reverted.

If you see another solution please help mу to find the best way of doing :)