yelp-fusion icon indicating copy to clipboard operation
yelp-fusion copied to clipboard

CORS ERROR when using Apollo Client to query Yelp Fusion

Open paolaguitian opened this issue 4 years ago • 9 comments

Overview

  • Issue type: CORS ERROR when using Apollo Client to query Yelp Fusion. Using Apollo Client v3
  • Summary: Access to fetch at https://api.yelp.com/v3/graphql from localhost is blocked by CORS.
  • Platform: Desktop

Description

When using Apollo Client to query Yelp Fusion, access is denied. When requesting https://api.yelp.com/v3 or https://api.yelp.com/v3/businesses/search from localhost both are blocked by CORS. Created client using @apollo/client createHttpLink and SetContext. Request fails console error is thrown. When sending curl through postman works fine as expected -- see parameters or sample request section below

More information

(Fill this section out if applicable (for things like bugs or questions))

Endpoint

https://api.yelp.com/v3/graphql https://api.yelp.com/v3/businesses https://api.yelp.com/v3/businesses/search

Parameters or Sample Request

cURL for https://api.yelp.com/v3/graphql - WORKS FINE

curl -X POST -H "Authorization: Bearer 2LoDZqt1aOH-XPiM1ef_kmKybmCiWC4zubqBznxU67xeHgcmg3SXXepn2bT-kavlQT4jwRwd9kZ0Z9zUrm-J_HwcJEKWMYklFbEyHjVz1MGwbeagllK0bJ4_JCMOX3Yx" -H "Content-Type: application/graphql" https://api.yelp.com/v3/graphql --data '
{
    business(id: "garaje-san-francisco") {
        name
        id
        alias
        rating
        url
    }
}'

Response

see snapshots Screen Shot 2020-07-21 at 3 08 26 PM Screen Shot 2020-07-21 at 3 08 46 PM

Extra information

Code:

import React from 'react';
import ReactDOM from 'react-dom';
import { ApolloClient, InMemoryCache, createHttpLink, gql } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import API_KEY from '../.env';
import App from './App';

const httpLink = createHttpLink({
  uri: 'https://api.yelp.com/v3/businesses/search',
  credentials: 'include',
});

const authLink = setContext((_, { headers }) => {
  return {
    headers: {
      ...headers,
      authorization: `Bearer ${API_KEY}`,
    }
  }
})
const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache(),

});

client.
  query({
    query: gql`
    query business {
      business(id: "garaje-san-francisco") {
        name
        id
        alias
        rating
        url
      }
    }
  `
  })
  .then(result => console.log(result))
ReactDOM.render(<App />, document.getElementById("root"));

I have tried adding headers like: Access-Control-Allow-Origin: *, content-type: application/json , content-type: application/graphql , added no-cors in the fetchOptions etc.. same error persist

paolaguitian avatar Jul 21 '20 19:07 paolaguitian

Unfortunately, according to my experience with Fusion, CORS is not supported. An alternative to using CORS client-side is to send a JSONP request, however, Fusion requires the Authorization header to be present, and headers aren't supported with JSONP. This renders it impossible to use the Fusion API client-side, which is why you see cURL working, since it doesn't require cross-origin support.

zaccanoy avatar Jul 27 '20 15:07 zaccanoy

@zaccanoy Thanks for the feedback & help, that's what I was thinking. However, what baffles me is that here: https://www.yelp.com/developers/graphql/guides/requests they state in the docs that they support Apollo Client specifically React and React Native so it should be implicated that any browser request to Yelp Fusion should not be blocked by cors

paolaguitian avatar Jul 27 '20 19:07 paolaguitian

@paolaguitian Great point, I missed that! Probably not helpful, but I do want to note that their GraphiQL editor uses their server as a proxy.

zaccanoy avatar Jul 27 '20 21:07 zaccanoy

Overview

  • Issue type: CORS ERROR when using Apollo Client to query Yelp Fusion. Using Apollo Client v3
  • Summary: Access to fetch at https://api.yelp.com/v3/graphql from localhost is blocked by CORS.
  • Platform: Desktop

Description

When using Apollo Client to query Yelp Fusion, access is denied. When requesting https://api.yelp.com/v3 or https://api.yelp.com/v3/businesses/search from localhost both are blocked by CORS. Created client using @apollo/client createHttpLink and SetContext. Request fails console error is thrown. When sending curl through postman works fine as expected -- see parameters or sample request section below

More information

(Fill this section out if applicable (for things like bugs or questions))

Endpoint

https://api.yelp.com/v3/graphql https://api.yelp.com/v3/businesses https://api.yelp.com/v3/businesses/search

Parameters or Sample Request

cURL for https://api.yelp.com/v3/graphql - WORKS FINE

curl -X POST -H "Authorization: Bearer 2LoDZqt1aOH-XPiM1ef_kmKybmCiWC4zubqBznxU67xeHgcmg3SXXepn2bT-kavlQT4jwRwd9kZ0Z9zUrm-J_HwcJEKWMYklFbEyHjVz1MGwbeagllK0bJ4_JCMOX3Yx" -H "Content-Type: application/graphql" https://api.yelp.com/v3/graphql --data '
{
    business(id: "garaje-san-francisco") {
        name
        id
        alias
        rating
        url
    }
}'

Response

see snapshots Screen Shot 2020-07-21 at 3 08 26 PM Screen Shot 2020-07-21 at 3 08 46 PM

Extra information

Code:

import React from 'react';
import ReactDOM from 'react-dom';
import { ApolloClient, InMemoryCache, createHttpLink, gql } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import API_KEY from '../.env';
import App from './App';

const httpLink = createHttpLink({
  uri: 'https://api.yelp.com/v3/businesses/search',
  credentials: 'include',
});

const authLink = setContext((_, { headers }) => {
  return {
    headers: {
      ...headers,
      authorization: `Bearer ${API_KEY}`,
    }
  }
})
const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache(),

});

client.
  query({
    query: gql`
    query business {
      business(id: "garaje-san-francisco") {
        name
        id
        alias
        rating
        url
      }
    }
  `
  })
  .then(result => console.log(result))
ReactDOM.render(<App />, document.getElementById("root"));

I have tried adding headers like: Access-Control-Allow-Origin: *, content-type: application/json , content-type: application/graphql , added no-cors in the fetchOptions etc.. same error persist

I am facing the same issuse.. were you able to figure out a solution for the same ?

vaishnavipy avatar Mar 11 '21 14:03 vaishnavipy

@vaishnavipy Unfortunately not! Had to abandon

paola-guitian-papa avatar Mar 11 '21 14:03 paola-guitian-papa

Try using the CORS Anywhere proxy, it worked for me.

Just set the request URL from https://api.yelp.com/v3 to https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3

and unlock the demo challenge by going to https://cors-anywhere.herokuapp.com first, or setup your own proxy: https://github.com/Rob--W/cors-anywhere/issues/301

From Yelp: "Yelp API doesn't support CORS and hence needs a server to connect with.

The auth flow we've built for the v3 API isn't suited towards being integrated directly from a client, it risks exposing sensitive information from inside the app."

https://stackoverflow.com/questions/43871637/no-access-control-allow-origin-header-is-present-on-the-requested-resource-whe

davidvm2 avatar Jul 16 '21 20:07 davidvm2

Try using the CORS Anywhere proxy, it worked for me.

Just set the request URL from https://api.yelp.com/v3 to https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3

and unlock the demo challenge by going to https://cors-anywhere.herokuapp.com first, or setup your own proxy: https://github.com/Rob--W/cors-anywhere/issues/301

From Yelp: "Yelp API doesn't support CORS and hence needs a server to connect with.

The auth flow we've built for the v3 API isn't suited towards being integrated directly from a client, it risks exposing sensitive information from inside the app."

https://stackoverflow.com/questions/43871637/no-access-control-allow-origin-header-is-present-on-the-requested-resource-whe

This works for me too! thanks

lhn136 avatar Aug 07 '21 22:08 lhn136

https://cors-anywhere.herokuapp.com/ is only intended for local development. It has limits on the number of redirects before re-activation. So it is not a solution for deployment unless you host your own cors-anywhere.

leimao avatar Mar 05 '22 03:03 leimao

https://cors-anywhere.herokuapp.com/ is only intended for local development. It has limits on the number of redirects before re-activation. So it is not a solution for deployment unless you host your own cors-anywhere.

i ran into this same problem. i ended up adding another endpoint to my backend express server that basically acts as a proxy to yelp's api

  app.use(cors({ origin: ["http://localhost:3000", "https://studio.apollographql.com"], credentials: true }));

  // Yelp CORS error https://github.com/Yelp/yelp-fusion/issues/579
  app.use(
    "/yelp",
    createProxyMiddleware({
      target: `https://api.yelp.com/v3/graphql`,
      changeOrigin: true,
      pathRewrite: {
        "^/yelp": ""
      },
      headers: {
        authorization: `Bearer ${process.env.YELP_API_KEY}`,
        "Accept-Language": "en-US"
      }
    })
  );

  const server = new ApolloServer({
    schema: makeExecutableSchema({ typeDefs, resolvers }),
    plugins: [ApolloServerPluginDrainHttpServer({ httpServer })]
  });

  // More required logic for integrating with Express
  await server.start();
  server.applyMiddleware({ app, path: "/graphql" });

ryanyue123 avatar Apr 03 '22 05:04 ryanyue123