Skip to content
This repository has been archived by the owner on Jul 1, 2020. It is now read-only.

Access to fetch at 'https://prismatest3.brunocrosier.now.sh/' from origin 'https://with-apollo-auth.brunocrosier.now.sh' has been blocked by CORS policy #2

Open
arbaouimehdi opened this issue Jan 23, 2020 · 7 comments

Comments

@arbaouimehdi
Copy link

You've a problem on your Demo that shows on the Google Chrome console:

Access to fetch at 'https://prismatest3.brunocrosier.now.sh/' from origin 'https://with-apollo-auth.brunocrosier.now.sh' 
has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' 
header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
POST https://prismatest3.brunocrosier.now.sh/ net::ERR_FAILED

I guess that prismatest3.brunocrosier.now.sh is blocked by CORS Policy, is there any solution to solve this problem, because everything works perfectly locally, except where I deploy the repo on zeit.co

@arbaouimehdi arbaouimehdi changed the title CORS header 'Access-Control-Allow-Origin' missing Access to fetch at 'https://prismatest3.brunocrosier.now.sh/' from origin 'https://with-apollo-auth.brunocrosier.now.sh' has been blocked by CORS policy Jan 23, 2020
@brunocrosier
Copy link
Owner

Hi @freemh that's because I've deleted https://prismatest3.brunocrosier.now.sh 😅

You should replace that URL with your own backend URL inside /frontend/next.config.js

Let me know if you have any difficulty with it

@arbaouimehdi
Copy link
Author

arbaouimehdi commented Jan 23, 2020

Hi @brunocrosier, thanks for your answer, I'm getting the same error from this domaine name https://mern-crud-admin.now.sh/ pointing at this https://mern-crud-api.now.sh.

Everything works perfectly locally, but once I deploy it on it trigger the CORS policy error.

This is the api code:

// Accessing Environment Variables
require("dotenv").config({
  path: `.env.${process.env.NODE_ENV}`
});

const { prisma } = require("./generated/prisma-client");
const { GraphQLServer } = require("graphql-yoga");
const cors = require("cors");

const cookieParser = require("cookie-parser");
const jwt = require("jsonwebtoken");

// Resolvers
const Mutation = require("./resolvers/Mutation");
const Query = require("./resolvers/Query");
const Post = require("./resolvers/Post");
const User = require("./resolvers/User");

// Secret
const { APP_SECRET } = process.env;

// import schema stuff
if (process.env.NODE_ENV !== "production") {
  const { importSchema } = require("graphql-import");
  const fs = require("fs");

  const text = importSchema(__dirname + "/schema.graphql");
  fs.writeFileSync("./schema_prep.graphql", text);
}

const resolvers = {
  Query,
  Mutation,
  User,
  Post
};

const server = new GraphQLServer({
  typeDefs: __dirname + "/schema.graphql",
  resolvers,
  context: request => {
    return { ...request, prisma };
  }
});

const corsOptions = {
  credentials: true,
  origin:
    process.env.NODE_ENV === "production"
      ? [process.env.PRODUCTION_FRONTEND_URL, process.env.PRODUCTION_ADMIN_URL]
      : ["http://localhost:3000", "http://localhost:6555"]
};

server.express.use(cors(corsOptions));

server.express.use(cookieParser());

// 2. decode the JWT so we can get the user Id on each request
server.express.use((req, res, next) => {
  const { token } = req.cookies;

  if (token) {
    const { userId } = jwt.verify(token, APP_SECRET);
    // put the userId onto the req for future requests to access
    req.userId = userId;
    // console.log("userId", userId);
  }
  next();
});

// 3. Create a middleware that populates the user on each request
server.express.use(async (req, res, next) => {
  // if they aren't logged in, skip this
  if (!req.userId) return next();

  const user = await prisma.user({ id: req.userId });
  req.user = user;
  // console.log("req.user", JSON.stringify(req.user));

  next();
});

server.start(
  {
    port: process.env.PORT,
    cors: {
      ...corsOptions
    }
  },
  () => console.log(`Server is running on http://localhost:${process.env.PORT}`)
);

@arbaouimehdi
Copy link
Author

@brunocrosier this is the link of the repo in question: https://github.com/freemh/mern-crud

@brunocrosier
Copy link
Owner

Hi @freemh I have cloned your project and found the issue.

in the frontend/init-apollo.js file on line 14 you will see this code, which decides whether we load the backend API from the local development server, or from the published one.

const httpLink = createHttpLink({
    uri:
      process.env.NODE_ENV === "production"
        ? process.env.API_URI
        : "http://localhost:7777",
    credentials: "include",
    fetchOptions
  });

If you change it from === to !== then your code will work (because it will fetch the data from https://mern-crud-api.now.sh instead of http://localhost:7777

If you don't want to run your backend API locally, you can just change the code to:

const httpLink = createHttpLink({
    uri: process.env.API_URI,
    credentials: "include",
    fetchOptions
  });

I hope that this helps you!

@arbaouimehdi
Copy link
Author

I already did that by setting the uri to process.env.API_URI as you described, and I even set it manually to uri: "https://mern-crud-api.now.sh/" still have the same problem.

I think that this problem is related to the server more than the client, plus the server.express.use(cors(corsOptions)); is not taking effect at all from the api "index.js" file.

Both solution doesn't work to allow different domain names:

const corsOptions = {
  credentials: true,
  origin:
    process.env.NODE_ENV === "production"
      ? [process.env.PRODUCTION_ADMIN_URL]
      : ["http://localhost:6555"]
};

server.express.use(cors(corsOptions));
const corsOptions = {
  credentials: true,
  origin: "https://mern-crud-admin.now.sh/"
};

server.express.use(cors(corsOptions));

What I don't really understand that everything works perfectly locally.

@brunocrosier
Copy link
Owner

Ah, I only tested this locally - so I think I misunderstood your issue initially.

I have recently built a more updated version of next + apollo + auth for a different project. I will try and tidy it up and then upload it.

In the meantime, this is the index.js for the backend folder for the new project.

require("dotenv").config()

const { prisma } = require("./generated/prisma-client")
const { GraphQLServer } = require("graphql-yoga")
const jwt = require("jsonwebtoken")
const { APP_SECRET } = require("./utils")
const Query = require("./resolvers/Query")
const Mutation = require("./resolvers/Mutation")

const cookiesMiddleware = require("universal-cookie-express")

console.log("process.env.NODE_ENV is: ", process.env.NODE_ENV)

console.log("process.env.PRISMA_SECRET is: ", process.env.PRISMA_SECRET)

// import schema stuff

if (process.env.NODE_ENV !== "production") {
  const { importSchema } = require("graphql-import")
  const fs = require("fs")

  const text = importSchema(__dirname + "/schema.graphql")
  fs.writeFileSync("./schema_prep.graphql", text)
}

const server = new GraphQLServer({
  typeDefs: __dirname + "/schema_prep.graphql",
  resolvers: {
    Query,
    Mutation
  },
  context: request => {
    return { ...request, prisma }
  }
})

server.use(cookiesMiddleware())


server.use((req, res, next) => {
  const token = req.headers.authorization

  if (token && token.length > 10) {
    const { userId } = jwt.verify(token, APP_SECRET)
    req.token = token
    req.userId = userId
  }

  next()
})

server.start(
  {
    cors: {
      credentials: true,
      origin: new RegExp("/*/")
    }
  },
  () => console.log("Server is running on http://localhost:4000")
)

Hopefully this can help you. If not, I will try and update this repo with the latest versions of everything

@arbaouimehdi
Copy link
Author

arbaouimehdi commented Jan 23, 2020

@brunocrosier I'll try to implement the new index.js and let you know, thanks for your time.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants