1

Access to XMLHttpRequest at 'https://checkoutapistage.svea.com/api/orders/142691' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I can't seem to get rid of the problem, tryed different "fixes" for CORS.

This is for a booking service that use a GraphQL DB with GraphQLserver from graphql-yoga to server and a React front end. That is working fine so far. But now I need to make calls to another api in order to see if payments are valid aswell as handling the actual payments. But then I get the error message from above.

I am not sure if I need to enable CORS on both back-end and front-end and I can't seem to solve this problem on my own. This is my current setup:

BACKEND Server.js

import { GraphQLServer, PubSub } from "graphql-yoga";
import { resolvers, fragmentReplacements } from "./resolvers/index";
import prisma from "./prisma";
const express = require("express");
const path = require("path");

const pubsub = new PubSub();

const server = new GraphQLServer({
  typeDefs: "./src/schema.graphql",
  resolvers,
  context(request) {
    return {
      pubsub,
      prisma,
      request
    };
  },
  fragmentReplacements
});

if (process.env.NODE_ENV === "production") {
  // Set static folder
  server.express.use(express.static("client/build/"));

  server.express.get("*", (req, res) => {
    res.sendFile(path.resolve(__dirname, "../client/build/index.html"));
  });
}

export { server as default };

index.js

import "@babel/polyfill/noConflict";
import server from "./server";
import job from "../cronJobs/sendLockCode";
import sameDayJob from "../cronJobs/sendLockCodeSameDay";

job.start();

sameDayJob.start();

server.start(
  {
    port: process.env.PORT || 4000,
    cors: {
      credentials: true,
      origin: [process.env.FRONTEND_URL]
    }
  },
  () => {
    console.log("The server is up!");
  }
);

FRONTEND

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { AuthProvider } from "./contexts/AuthContext";
import { ApolloLink, InMemoryCache, HttpLink } from "apollo-boost";
import { ApolloClient } from "apollo-client";
import { ApolloProvider } from "react-apollo";
import { split } from "apollo-link";
import { WebSocketLink } from "apollo-link-ws";
import { getMainDefinition } from "apollo-utilities";
import { hmac, timestamp } from "./components/utility/tokenGeneration";
// import { token } from "./components/utility/payment";
import axios from "axios";

const header = { Authorization: "Svea " + hmac, Timestamp: timestamp };

const corsOptions = {
  origin: "http://localhost:3000",
  credentials: true
};

var HOST;

if (window.location.origin !== "http://localhost:3000") {
  HOST = window.location.origin.replace(/^http/, "ws");
} else {
  HOST = "ws://localhost:4000";
}

const httpLink = new HttpLink({
  uri: "/"
});

const wsLink = new WebSocketLink({
  uri: HOST,

  options: {
    reconnect: true,
    connectionParams: {
      authToken: localStorage.getItem("Jaktiatoken")
    }
  }
});

const authLink = new ApolloLink((operation, forward) => {
  // Retrive the authorization token from local storage.
  const token = localStorage.getItem("Jaktiatoken");

  // Use the set Context method to set the HTTP headers.
  operation.setContext({
    headers: {
      authorization: token ? `Bearer ${token}` : ""
    }
  });

  // Call the next link in the middleware chain.
  return forward(operation);
});

const link = split(
  ({ query }) => {
    const { kind, operation } = getMainDefinition(query);
    return kind === "OperationDefinition" && operation === "subscription";
  },
  wsLink,
  authLink.concat(httpLink)
);

const client = new ApolloClient({
  link,
  cache: new InMemoryCache()
});

axios
  .get(`https://checkoutapistage.svea.com/api/orders/142691`, header)
  .then(res => console.log(res))
  .catch(err => console.log(err));

ReactDOM.render(
  <BrowserRouter>
    <AuthProvider>
      <ApolloProvider client={client}>
        <App />
      </ApolloProvider>
    </AuthProvider>
  </BrowserRouter>,
  document.getElementById("root")
);

export { client };

And yes, if things look weird and messy, they probably are, this is my first major project and I am doin it pretty much on my own.

/Cheers in advance, Sebastian

  • CORS is a setting on the backend you have to allow cors with * (all) origins. Becareful because this might be dangerous it is a good pratice to only let the requests come from one source. If you are using chrome you can also try: https://stackoverflow.com/questions/3102819/disable-same-origin-policy-in-chrome – Ricardo Costa Nov 14 '19 at 15:23
  • It looks like the SveaCheckout API does not allow requests from other origins. What you can do to bypass this is to create an endpoint in your own backend that requests the external API endpoint. CORS policies does not apply in a non-browser-environment. – hbentlov Nov 14 '19 at 15:40
  • It also makes sense to make the request in your backend since you don't want to expose your secret API key on the frontend. – hbentlov Nov 14 '19 at 15:56
  • @hbentlov Yes I think you are right about this cause I tryed with other API's and I can contact those without any problems. I have no idea how to do this, do you know where I can find out more information about how to do this? And also how do I access the backend when doin calls from my frontend? – Sebastian Berg Nov 18 '19 at 07:14
  • I would recommend looking into the [Express](https://expressjs.com) documentation to understand how to set up your own [routes](https://expressjs.com/en/guide/routing.html). You basically want to create routes that in their turn request the third party API with the secret key attached, using an HTTP client like [axios](https://www.npmjs.com/package/axios) and return the response back in the route. – hbentlov Nov 19 '19 at 10:49

0 Answers0