Yelp / yelp-fusion

Yelp Fusion API
https://yelp.com/developers
MIT License
401 stars 394 forks source link

CORS ERROR when using Apollo Client to query Yelp Fusion #579

Closed paolaguitian closed 9 months ago

paolaguitian commented 4 years ago

Overview

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

zaccanoy commented 4 years ago

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.

paolaguitian commented 4 years ago

@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

zaccanoy commented 4 years ago

@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.

vaishnavipy commented 3 years ago

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 ?

paola-guitian-papa commented 3 years ago

@vaishnavipy Unfortunately not! Had to abandon

davidvm2 commented 3 years ago

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

lhn136 commented 3 years ago

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

leimao commented 2 years ago

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.

ryanyue123 commented 2 years ago

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" });