I'm having a problem getting the cookie with my auth token to pass as part of my requests. When I look in Chrome after my authentication request is fulfilled, the response cookie is appropriately set, but it is never passed into additional requests.
Express route for /login that generates the cookie:
router.get('/login',
passport.authenticate('local', {
session: false
}),
function(req, res) {
console.log('/login authentication successful');
token.generate(req.users, function(result) {
res.cookie('access_token', result, {
//secure : true,
//maxAge : 1000*60*60, // 1 hour
path: '/',
httpOnly: true
});
res.json(Response.success(req.user));
});
}
);
I also have the following for setting the headers:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", true);
next();
});
Now in Angular, I am passing a config object to my $http request with withCredentials: true, but so far, nothing has worked.
$http({
method: 'GET',
url: 'http://localhost:3000/api/v1/devices',
withCredentials: true
}).then(function successCallback(response) {
// do stuff
}, function errorCallback(response) {
// oh noes!
});
A note about my setup: I have one node server running to provide the backend on port 3000, with another node server using browserSync to display the clientside on port 8080. I've seen a suggestion that using http://localhost:8080 instead of an IP could cause the cookie to not get passed, but that doesn't appear to make a difference.
Hopefully one of you fine guys or gals will have an inkling as to what my problem is. Thanks!
seem to be missing header for Access-Control-Allow-Methods which would include verbs used "OPTIONS,POST,GET,PUT,DELETE" etc
Reference MDN HTTP access control (CORS)
I don't use node a lot for cors but I know there are packages that will do all this for you
Related
Having a react frontend with my own expressjs api backend.
Express v. 4.16.0
Using fetch on the react frontend to get data works just fine.
fetch('/desResData')
.then(res => {....}
As soon as I try to post some data with the request I get: "POST http://localhost:3000/desResData 404 (Not Found)"
Code:
fetch('/desResData',
{
method: 'POST',
body: { product: "test" }, // tried JSON.stringify as well
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}
)
.then(res => {....}
Roughly spoken I can have static communication from front to backend but I cant parametrize my requests.
ExpressJS:
router.get('/', async function (req, res, next) {
console.log(req.body) // tried with using req and without using it
findByProduct("product") // some async db operation // this part is working fine while fetching without any post parameters
.then(data => {
res.json()
})
You have to write router.post (not router.get) to process an HTTP POST request.
Notice the method of your fetch is POST. But you wrote router.get which handles a request where the method is GET.
If a POST request comes in for a route that doesn't exist, express will give 404. This applies even if there is a GET handler for the same route.
(Hint: you can have separate GET, POST, PUT, DELETE, etc. handlers for the same route by using .get, .post, .put, .delete, etc.)
add this in your server code :
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
next();
});
inside package.json of your react code :
"proxy": "http://localhost:serverport", <-- server port will be port of your node-express server
I'm trying to make a call to my API on Jazz using Vue.js and Axios, but I am getting the following error:
Access to XMLHttpRequest at 'https://jazz.api.com/api/extra_stuff
_here' from origin 'http://localhost' 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.
I've been looking at other solutions like https://enable-cors.org/server_expressjs.html or adding
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Credentials": "true"
to my code and it still didn't work. Even if I do the wildcard for the Access-Control-Allow-Origin, I still get the CORS issue and cannot call my API. I am using Vue and Typescript for the client side and managed to get Express working for my server side. Here is a code snippet of my Axios API call:
return Axios.post('https://jazz.api.com/api/extra_stuff_here', context.getters.getRequest,
{
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Credentials": "true"
}
}
)
This is where I am calling my API in this TypeScript file and here is my server.js:
var express = require('express');
var path = require('path');
var cors = require('cors');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var app = express();
app.use(morgan('dev'));
app.use(cors());
app.use(bodyParser.json());
var publicRoot = './dist';
//app.use(express.static(path.join(__dirname, '/dist')));
app.use(express.static(publicRoot));
app.get('/', function (req, res) {
res.sendFile("index.html", { root: publicRoot });
});
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Authorization");
res.header("Content-Type", "application/json");
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
res.header("Access-Control-Allow-Credentials", "true");
next();
});
app.listen(process.env.PORT || 80, function() {
console.log("listening on port 80");
});
No matter what I seem to do, I cannot figure out this CORS issue. Before I added express to my application, I still got the same issue, thinking that maybe express on the server side would fix the CORS issue. However it didn't help. Beforehand, I was running my Vue application by doing npm run serve. But any help would be great! Could it possibility be an issue with Jazz?
You’ve added the cors middleware but haven’t enabled it for OPTIONS requests
app.options('*', cors())
Try adding something like this to your server to enable it.
You can read further in the express docs here
https://expressjs.com/en/resources/middleware/cors.html
Update: I didn't manage to fix the CORS issue with Axios, but I did manage to find a workaround for this. Instead of using the Axios library, I am using fetch to call the API. Since all I need to do with my request call is to pass in parameters and get back data based on the parameters, my application works with fetch. While I was doing my research, I saw that there may be issues or limitations using fetch? But hey, it works for me so I'll be sticking with this solution. Here is my code as reference for anyone:
return fetch('https://dev.jazz.com/api/stuff_goes_here', {
method: 'post',
body: JSON.stringify(<request object goes here>)
}).then((res) => res.json())
.then((data) => {
return data;
}).catch((err)=>console.log(err))
I have an node js API.
app.post('/myapi', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Request-With");
res.header("Content-Type", "application/json");
res.header("Accept", "application/json");
* do something *
res.json({ api : "api called successfully" });
});
I have a html code placed in the public folder. I am using express to run both the html code and backend APIs.
My html code has request fetch as,
var headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json, text/plain, */*');
var options = {
method: 'POST',
body: JSON.stringify(loginDetails),
headers: headers,
mode: 'no-cors'
};
fetch('http://localhost:3001/myapi', options)
.then(function (response) {
console.log(response);
res=response.statusCode;
// return response
if (res==0) {
window.location.assign("http://localhost:3001/home.html");
}
});
When I run the code in browser. When I click on a button that calls the above frontend code. It sends two request. Both the call fails. One is localhost request which is document call and other is the API call. But there is no response in the API call.
I was getting response in UI from the / call,
cannot POST/
So I tried adding following code,
app.post('/', function (req, res) {
res.json({ "status": "successfull" });
});
Now also there is two calls but UI returns {status : successfull} (output of /). But it is not returning output of /myapi.
Can someone please help?
I am getting an infinity initiator for localhost document. See the screenshot.
Append any unique parameter to request to avoid sending cached version of request.
/api/name?id=<unique_param>
You can find more details here and here.
I'm using Express for webserver, and using isomorphic-fetch module from client to using XHR.
I have three servers for my web application:
Port 3000 -> Admin Website
Port 3001 -> Public Website
Port 3002 -> API Server
API Server has resources named "skills" which has some data, and get it like this:
GET http://mydomain:3002/skills
it returns JSON data.
But when I request to 3002 from 3000/3001, it fails with this message:
Fetch API cannot load http://example.me:3002/skills. Redirect from 'http://example.me:3002/skills' to 'http://example.me:3002/skills/' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect.
I don't get it why there is 'redirection' or something. This is my server side code, I granted all CORS related headers:
const express = require('express');
const app = express();
...
// CORS
app.use((req, res, next) => {
var allowedOrigins = ['http://example.me', 'http://example.me:3000', 'http://example.me:3001', 'http://example.me:3002'];
var origin = req.headers.origin;
if(allowedOrigins.indexOf(origin) > -1){
res.setHeader('Access-Control-Allow-Origin', origin);
}
res.setHeader('Access-Control-Allow-Credentials', true);
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
if (req.method === "OPTIONS") {
return res.status(200).end();
}
next();
});
app.use(require('./routes'));
...
app.listen(3002, () => console.log(".API Server listening on port 3002..."));
And this is client side code that using Fetch API:
fetch('http://example.com:3002/skills', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
credentials: 'include',
cache: 'no-store',
mode: 'cors'
})...
As you can see there is no redirection code. I spent almost a day to fix this issue, but everything I tried was all failed, every information that I found was useless.
I think splitting services to API Server and Web Server(actually returns HTML) was good idea, and want to go with this approach.
Is there a way to fix this problem? Any advice will very appreciate.
I solved this issue few years ago, still don't get it why it happened.
However my solution was simple, put every API into /api path.
I keep facing the same error over and over again:
XMLHttpRequest cannot load http://localhost:3000/form. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 404.
I've read countless posts similar to this one and they all pretty much have the same answer, namely to add the following setting: res.setHeader('Access-Control-Allow-Origin', '*').
That's what I've been doing but it still doesn't work.
I gave an angular.js app on localhost:8000 (when a btn is clicked logsth() is called) and my node works on localhost:3000. Here's what they look like:
app.controller('Contact', ['$scope', function($scope) {
$scope.logsth = function(){
var datas = {'may':'4','june':'17'};
$.ajax({
url: 'http://localhost:3000/form',
method: 'POST',
crossDomain: true,
data: datas
});
};
}]);
And my node:
var express = require('express');
var router = express.Router();
var app = express();
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.post('/form', function(req, res){
console.log("e-mail sent");
res.send('yey');
});
module.exports = router;
Not too much code here but for now I'm only looking to get rid of the error.
EDIT: When I use app.use(...) and app.post(...) and go to localhost:3000/form I get 404 error. But when I use router.use(...) and router.post(...) at least the link works fine. Also, there is no 'allow-origin' error, but I do get: POST http://localhost:3000/form 404 (Not Found). However, when I go to http://localhost:3000/form it displays the response and console.log. Should I leave it as router instead of app?
Just leave this single line did the trick for me:
res.setHeader('Access-Control-Allow-Origin', '*');
Update:
You can try to install cors module from npm.
The issue is that you're returning a wildcard origin (*) and trying to pass credentials (res.setHeader('Access-Control-Allow-Credentials', true);). You cannot to both. If you must use Access-Control-Allow-Credentials, then you will need to be explicit about the allowed origins in your Access-Control-Allow-Origin header.
So, either remove this:
res.setHeader('Access-Control-Allow-Credentials', true);
Or change the origins to this:
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');