I have cors error while using Socketio v3
the app is on React backed by Nodejs
Server Side Codes:
var server = http.createServer(app);
var port = process.env.PORT || '3000'
const io = require("socket.io")(server,{
cors: {
origin: "*:*",
methods: ["PUT", "GET", "POST", "DELETE", "OPTIONS"],
allowedHeaders:["secretHeader"],
credentials: true
}
})
Client Side Connecting code:
const SOCKET_URL = "https://fakeurl.org";
socket.current = io(`${SOCKET_URL}`,{
secretHeader:{
"Access-Control-Allow-Headers": "*"
}
});
And i got the following error:
Access to XMLHttpRequest at
'https://fakeurl.org/socket.io/?EIO=4&transport=polling&t=NOdqBkN'
from origin 'http://localhost:3000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested
resource.
Refer to Socket.io Handling CORS.
// server-side
const io = require("socket.io")(server,{
cors: {
origin: "*",
methods: ["PUT", "GET", "POST", "DELETE", "OPTIONS"],
allowedHeaders:["secretHeader"],
credentials: true
}
})
// client-side
const SOCKET_URL = "https://fakeurl.org";
socket.current = io(`${SOCKET_URL}`,{
withCredentials: true,
extraHeaders: {
"secretHeader": "secret value"
}
});
Related
I am having this problem when trying to use withCredentials that it tells me that I need
Access to XMLHttpRequest at 'http://localhost:3005/api/v1/user' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
Uncaught (in promise) AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}
async function getUser() {
const user = await axios.get("http://localhost:3005/api/v1/user", {
withCredentials: true, headers: {
'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'
}
});
console.log(user)
}
useEffect(() => {
getUser();
}, [])
Researching this people are telling me that I need to activate cors on the server. But from what I can tell I have already done that by doing this + npm I cors.
const cors = require('cors')
var app = express();
const corsOptions ={
origin:'*',
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200,
}
app.use(cors(corsOptions))
If I remove the withCredentials everything works fine the problem is that I need the connect.sid cookie on the server in order to log in the user.
I have had this problem before. Solved it by changing the * to ['http://localhost:3000']
So your code should say:
const cors = require('cors')
var app = express();
const corsOptions ={
origin:['http://localhost:3000'],
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200,
}
app.use(cors(corsOptions))
I want the react application to be able to store cookies in the cookie storage of browser.
I am required to send withCredentials: true in headers in axios.
axios.defaults.withCredentials = true
export const login = (email, password) => {
return axios({
method: "POST",
url: "https://api.*****.**/login",
data: {
email: email,
password: password,
},
});
};
On the backend I am using ExpressJS cors middleware
const cors = require("cors");
const corsOptions = {
credentials: true,
};
app.use(cors(corsOptions));
On making login request from react using axios, in response I am getting error:
Access to XMLHttpRequest at 'https://api.*****.**/login' from origin 'http://localhost:3000' has been blocked by CORS policy:
Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
From res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true }) remove domain in option
I am using Heroku to run my server, and I am using 'cores' at my backend side that wrote in Node.js.
I have these commands:
const corsConfig = {
origin: true,
credentials: true
};
app.use(cors(corsConfig));
app.options("*", cors(corsConfig));
in my client i am using vue.js:
module.exports = {
devServer: {
proxy: {
'/api': {
target: '"https://david-matan-recipe-api-server.herokuapp.com/',
ws: true,
changeOrigin: true
}
}
}
}
when I am trying to get some data from my backend with Axios I get this message at my browser:
Access to XMLHttpRequest at 'https://david-matan-recipe-api-server.herokuapp.com/api/recipes/random' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
try to set config like this:
const corsConfig = {
origin: 'http://localhost:8080'
};
I can not access the "Authorization" header in each HTTP request on my Apollo-Server, implemented with express.
Here is my setup of express, Apollo-Server, CORS, etc.
const corsConfig = {
credentials: true,
allowedHeaders: ['Authorization'],
exposedHeaders: ['Authorization']
};
const app = express()
const server = new ApolloServer({
schema,
context: ({ req }) => {
return {
req
};
}
});
server.applyMiddleware({
app,
path,
cors: corsConfig
});
http.createServer(app).listen(port, () => logger.info(`Service started on port ${port}`));
And inside my resolvers, I bring in the context, particularly the req object (this is an example graphQL endpoint resolver):
const exampleQuery = async (parent, input , { req }) => {
console.log(req.headers);
/*
The output of this log:
{
'content-type': 'application/json',
accept: '*/*',
'content-length': '59',
'user-agent': 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)',
'accept-encoding': 'gzip,deflate',
connection: 'close',
host: 'localhost:3301',
'Access-Control-Allow-Headers': 'Authorization',
'Access-Control-Expose-Headers': 'Authorization'
}
*/
}
I have sent requests to this endpoint, with an "Authorization" header, containing a token as the value. However, the Authorization header is not in the req.headers object (in fact, it's not in the entire req object either). I am certain that my Postman/Insomnia HTTP requests to this endpoint are sending out the Authorization header, however it seems to be not getting through my Apollo-Server.
Anyone have any insight as to why the Authorization header is not going through?
SOLUTION:
The problem was actually that I am using an Apollo federated microservices architecture, which requires additional configuration on the gateway to pass the Authorization header onto the individual microservices, where the resolvers are. You have to add the buildService function inside the ApolloGateway constructor, where you specify that a RemoteGraphQLDataSource willSendRequest of context.req.headers.authentication to the underlying microservices
It works as expected, E.g.
server.ts:
import { ApolloServer, gql, makeExecutableSchema } from 'apollo-server-express';
import express from 'express';
import http from 'http';
const corsConfig = {
credentials: true,
allowedHeaders: ['Authorization'],
exposedHeaders: ['Authorization'],
};
const typeDefs = gql`
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: (_, __, { req }) => {
console.log(req.headers);
return 'world';
},
},
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
const app = express();
const path = '/graphql';
const port = 3000;
const server = new ApolloServer({
schema,
context: ({ req }) => {
return {
req,
};
},
});
server.applyMiddleware({ app, path, cors: corsConfig });
http.createServer(app).listen(port, () => console.info(`Service started on port ${port}`));
Send a GraphQL query HTTP request via curl:
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer abc123" --data '{ "query": "{ hello }" }' http://localhost:3000/graphql
{"data":{"hello":"world"}}
Server-side logs:
Service started on port 3000
{ host: 'localhost:3000',
'user-agent': 'curl/7.54.0',
accept: '*/*',
'content-type': 'application/json',
authorization: 'Bearer abc123',
'content-length': '24' }
I have been trying to do an api call (nodejs with express running on localhost) from a react app running in the browser over a local dev server (web-pack dev server). Everything was working well until I tried to call the api. They are both running on separate ports.
I have tried adding the cors headers (Recommended by MDN) to both the post call (from the app in browser) and to the response from the Nodejs API but neither of these solved the issue.
Code for the api call (in browser):
const headers = {
'Content-Type': 'application/json',
'access-token': '',
'Access-Control-Allow-Origin': '*',
}
export default async () => {
try {
const body = JSON.stringify({
test: true,
})
const response = await fetch('http://localhost:1337/internal/provider/check_email_exist', {
method: 'POST',
headers,
body,
})
console.log(response)
} catch (e) {
return e
}
}
API Middleware (in nodejs):
// Verify All Requests
app.use(VerifyToken)
// Compress
app.use(compression())
// Helmet middlware
app.use(helmet())
// Body Parser
app.use(bodyParser.urlencoded({
extended: false,
}))
app.use(bodyParser.json())
The expected result is to just give a 200 status code and respond with the data.
The actual output is:
OPTIONS http://localhost:1337/internal/provider/check_email_exist 404 (Not Found)
Access to fetch at 'http://localhost:1337/internal/provider/check_email_exist' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Since you're using webpack-dev-server you can use the proxy option DevServerProxy.
Your configuration will look like this:
// webpack.config.js
devServer: {
proxy: {
'/internal': 'http://localhost:1337'
}
}
Since I can't see your express routes on your question I'm speculating about the proxy route if your API lives on /internal endpoint then you should modify your React code like this:
const response = await fetch('/internal/provider/check_email_exist', {
method: 'POST',
headers,
body,
})
As you can see I ommited the https://localhost:1337 because the proxy option from webpack-dev-server will handle this and it will redirect to http://localhost:1337. Hope this will help you. Cheers, sigfried.
EDIT
As the comment on your question pointed out you should set the headers on your express server, not the client, for this task you can use the cors-middleware package.
Maybe this can help if you face with preflight errors.
My full config:
const cors = require('cors');
const express = require('express');
const { createProxyMiddleware: proxy } = require('http-proxy-middleware');
...
const logLevel = 'info';
const ip = require('ip').address();
const proxyOptions = {
xfwd: true,
target,
changeOrigin: true,
logLevel,
cookieDomainRewrite: {
'*': 'localhost',
},
headers: {
'X-Forwarded-For': ip,
'X-Node': 'true',
},
};
const backNginxApp = express();
backNginxApp.use(
cors({
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
origin: 'http://localhost:3000',
optionsSuccessStatus: 200,
credentials: true,
})
);
backNginxApp.use('/api', proxy(proxyOptions));
API: const target = 'https://someapi.com'
Local development running at: http://localhost:3000