I'm making a PATCH request from a client running on localhost:3000 with the following code:
axios.patch(
"http://localhost:3090/v1/users/etc/etc/etc", {
name,
url,
}, {
headers: {
authorization: AUTH_TOKEN()
}
}
)
To a server configured as follows:
var app = express();
var cors = require('cors');
//etc
//var whitelist = [
// 'http://localhost:3000',
// 'localhost:3000'
//];
//passing this to cors() doesn't help
//var globalCorsOptions = {
// origin: function(origin, callback) {
// callback(null, whitelist.indexOf(origin) !== -1);
// }
//};
app.use(morgan('combined'));
app.use(cors());
app.options('*', cors());
app.use(bodyParser.json({type:'*/*'}));
app.use('/v1', router);
var port = process.env.PORT || 3090;
var ip = process.env.IP || 'localhost';
var server = http.createServer(app);
server.listen(port, ip);
But the request just hangs. I can do POST/GET fine, but not DELETE/PATCH. The preflight happens fine but the actual request following just sits "stalled" indefinitely. Here's the headers for each request:
Sorry to ask this pretty standard question, but I've tried everything.
EDIT:
Added the following to router (still not working):
var router = express.Router();
router.use(function(req, res, next) {
res.header("Access-Control-Allow-Headers", "PATCH,DELETE,OPTIONS,GET,POST");
next();
});
The actual error:
On the server you have to add following header to the response:
headers.Add("Access-Control-Allow-Headers", "PATCH,DELETE,GET,POST");
Actually all HTTP methods you want to allow.
Related
I am trying to make Postman work with React JS using express. I am following a Mern Stack Development tutorial in free code camp. I have Cors extension enabled in my browsers, both in Chrome and in Edge. I keep getting this message in localhost:5000 "Cannot get /" and get this message {"msg":"This is CORS-enabled for an allowed domain."} in localhost:5000/users/add. My code looks something like this:
This is my server.js
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();
const app = express();
const port = process.env.PORT || 5000;
app.use(cors());
app.use(express.json());
const uri = process.env.ATLAS_URI;
mongoose.connect(uri,{useNewUrlParser: true, useCreateIndex:true, useUnifiedTopology:true});
const connection= mongoose.connection;
connection.once('open', () =>{
console.log("Mongodb database connection established successfully");
})
const exercisesRouter= require('./routes/exercises');
const usersRouter= require('./routes/users');
var allowlist = ['http://localhost:5000']
var corsOptionsDelegate = function (req, callback) {
var corsOptions;
if (allowlist.indexOf(req.header('Origin')) !== -1) {
corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
} else {
corsOptions = { origin: false } // disable CORS for this request
}
callback(null, corsOptions) // callback expects two parameters: error and options
}
app.use('./exercises',exercisesRouter);
app.use('./users', usersRouter);
app.get('/users/add', cors(corsOptionsDelegate), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for an allowed domain.'})
})
app.listen(port, ()=>{
console.log(`Server is running on port: ${port}`);
});
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
cords don’t have anything to do with this
Can you tell me where is yow route for “/“ something like this
app.get(“/“, (req,res)=>{
…..
});
Yes exactly. You don’t have it. If the route/endPoint is not declared how do use expect them browsers to show you some else
When browssers open yow link at localhost:5000
They make a get request to “/“. So express just tell’em
Can not get “/“
I do not
I am trying to send an Ajax request to a Nodejsserver from my application, but getting this error
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I am sending request using ajax call to a server (nodejs), server in turn will return url , in success function, should redirect the url sent by server.
//nodejs app.js
var express = require('express');
var app = express();
var cors = require('cors');
var link= require('./routes/link');
app.use('/quote', link);
app.use(cors());
module.exports = app;
//link.js
var express = require('express');
var app = express();
var cors = require('cors');
var router = express.Router();
router.get('/', function (req, res) {
res.send({ redirectUrl: "https://www.google.com" });
});
module.exports=router;
//frontend
$.ajax({
method: 'get',
url: '/quote',
data: {
id: "1",
cn: "IN",
},
success: function (result) {
window.location.href = result.redirectUrl; // url got from server
},
error: function (request, status, error) {
console.log(request.error);
}
});
You can custom cors instead of app.use(cors()); like this:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
});
Let try it.
Order matters here just move "app.use(cors());" above "app.use('/quote',link);" like this. I doubt you need to fill out the custom fields in cors, the correct order should fix the problem.
//nodejs app.js
var express = require('express');
var app = express();
var cors = require('cors');
var link= require('./routes/link');
app.use(cors());
app.use('/quote', link);
...
i am quiet new to express . I have searched a lot and unable to find the answer.
i am receiving headers in my express app, but when i try to set those headers to be accessible by angular, it returns undefined. how ever hard coded header appears perfectly at angular end in networks tab of chrome. Here is the code
express code
var express = require('express');
var config = require('./config')[process.env.NODE_ENV || 'dev'];
var app = express();
app.get('/*', function (req, res) {
res.sendFile(__dirname + '/public/index.html');
var token=req.header('x-access-token');
//var token='123'
console.log(token);
res.set('x-access-token',token);
});
var server = app.listen(process.env.PORT || 3000, function() {
console.log('server started. Listening on port '+3000);
});
Angular code
$http.get($scope.windowURL
).
success(function(data, status, headers, config) {
$scope.token=headers('x-access-token')
console.log($scope.token);
alert($scope.token)
})
.error(function(data, status, headers, config) {
alert('notoken')
});
and i am getting 'undefined' in headers if set dynamically by express app.
You should set the header, before finishing the response with res.sendFile();
var express = require('express');
var config = require('./config')[process.env.NODE_ENV || 'dev'];
var app = express();
app.get('/*', function (req, res) {
var token=req.header('x-access-token');
//var token='123'
console.log(token);
res.set('x-access-token',token);
res.sendFile(__dirname + '/public/index.html');
});
var server = app.listen(process.env.PORT || 3000, function() {
console.log('server started. Listening on port '+3000);
});
How do I protect a post call from a angular2 application to a Express server?
In my angular2 application I have a the following HTTP Post.
const headers = new Headers();
headers.append('Content-Type', 'application/json');
const data = {
email: this.form.value.email
};
this.http.post('http://localhost:8080/api/user/email', data, {
headers: headers
})
Now I want to make sure that only my angular 2 application can make the post call to the user api. I did some research about csrf in combination with Express and Angular 2. In my Angular 2 application I made the following implementation to the app.module.ts file.
import { HttpModule, XSRFStrategy, CookieXSRFStrategy } from '#angular/http';
providers: [ {
provide: XSRFStrategy,
useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken')
} ]
I think this is the right way to implement a XSRFStrategy to Angular 2?
For the implementation in Express I followed a few tutorials, but without any success. Most of the time I received:
ForbiddenError: invalid csrf token
How do I implement the CSRF part in my Express api. Here is my Express config:
// call the packages we need
var express = require('express'); // call express
var app = express(); // define our app using express
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var csrf = require('csurf');
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
var port = process.env.PORT || 8080; // set our port
// ROUTES FOR OUR API
// =============================================================================
var router = express.Router();
router.use(function (req, res, next) {
console.log('Something is happening.');
res.setHeader("Access-Control-Allow-Origin", "http://localhost:4200");
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("Access-Control-Allow-Methods", "POST");
res.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
res.setHeader('Content-Type', 'application/json');
next();
});
app.use('/api', router);
router.post('/user/email', function (req, res) {
..... [how to make sure that this post can only be fired from my angular 2 application ]
}
Update #1
Did some more research and found the following in the Angular 2 docs:
//By default, Angular will look for a cookie called `'XSRF-TOKEN'`, and set
//* an HTTP request header called `'X-XSRF-TOKEN'` with the value of the cookie on each request,
So in my Express application I added the following parts:
const cookieOptions = {
key: 'XSRF-TOKEN',
secure: false,
httpOnly: false,
maxAge: 3600000
}
var csrfProtection = csrf({
cookie: cookieOptions
})
and in the post route I implemented the protection as follow:
router.post('/user/email', csrfProtection, function (req, res) {
console.log('post incomming');
}):
I got the following response headers back
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers
Access-Control-Allow-Methods:POST
Access-Control-Allow-Origin:http://localhost:4200
Connection:keep-alive
Content-Length:1167
Content-Type:text/html; charset=utf-8
Date:Mon, 21 Nov 2016 20:07:12 GMT
set-cookie:XSRF-TOKEN=O4JKkjAZRik2H7ml0DoxDc8s; Max-Age=3600000; Path=/
X-Content-Type-Options:nosniff
X-Powered-By:Express
And the request headers:
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8,nl;q=0.6
Connection:keep-alive
Content-Length:38
content-type:application/json
Host:localhost:8080
Origin:http://localhost:4200
Referer:http://localhost:4200/profile/users
How to implement CSRF protection with Angular2 and Express
By default, Angular will look for a cookie called 'XSRF-TOKEN', and set
an HTTP request header called 'X-XSRF-TOKEN' with the value of the cookie on each request.
To make sure that our backend can set a XSRF-TOKEN cookie, we have to proxy our calls to the api running on port 8080. We can do that with a proxy.config.json file.
{
"/api/*" : {
"target": "http://localhost:8080",
"secure": false,
"logLevel": "debug"
}
}
And in our package.json file we modify the scripts/start function to use our proxy.config.json file:
"scripts": {
"start": "ng serve --proxy-config proxy.config.json",
}
Now every time we run npm start our calls to /api are proxied to localhost:8080. Now we are ready to make a post call to our api server.
In our component we make a http post call and we set the headers to use content-type application/json.
ourfunction() {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
data = { key:value }
this.http.post('/api/user/email', data, {
headers: headers
}).subscribe( (resp: any) => console.log('resp', resp));
}
That is everything we need to do at the Angular2 side. Now we are implement the Express side.
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var csrf = require('csurf');
var cors = require('cors')
We initialise our app and defining some middleware to use in our application.
const cookieOptions = {
key: 'XSRF-TOKEN',
secure: false,
httpOnly: false,
maxAge: 3600
}
const corsOptions = {
origin: 'http://localhost:4200',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
};
Here we are setting the options to use for csrf and cors middleware.
const port = process.env.PORT || 8080; // set our port
const csrfProtection = csrf({ cookie: cookieOptions })
const router = express.Router();
Implementing the middelware. The order is very important to get the correct results.
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use('/api', router);
app.use(cors(corsOptions));
app.use(cookieParser());
app.use(csrfProtection);
router.use(function (req, res, next) {
res.setHeader('Content-Type', 'application/json');
next();
});
Thats all we need to do on the Express side. Now we can secure our post calls with a CSRF token.
Compleet express server file
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var csrf = require('csurf');
var cors = require('cors')
const cookieOptions = {
key: 'XSRF-TOKEN',
secure: false,
httpOnly: false,
maxAge: 3600
}
const corsOptions = {
origin: 'http://localhost:4200',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
};
const port = process.env.PORT || 8080; // set our port
const csrfProtection = csrf({ cookie: cookieOptions })
const router = express.Router();
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use('/api', router);
app.use(cors(corsOptions));
app.use(cookieParser());
app.use(csrfProtection);
router.use(function (req, res, next) {
res.setHeader('Content-Type', 'application/json');
next();
});
router.post('/user/email', function (req, res) {
console.log('post incomming');
console.log('req', req.body);
res.send('testing..');
});
app.listen(port);
console.log('Magic happens on port ' + port);
I am trying to implement the simplest example:
var http = require('http'),
var httpProxy = require('http-proxy');
httpProxy.createServer(function (req, res, proxy) {
//
// I would add logging here
//
proxy.proxyRequest(req, res, { host: 'www.google.com', port: 80 });
}).listen(18000);
When I configure my browser to use this proxy and I navigate to www.google.com I receive no response. What is that I am doing wrong?
I'm using Windows 7 Chrome
Here is an simple example how to log requests.
I use a similar to log all my domains to one database.
I copied much from http://blog.nodejitsu.com/http-proxy-middlewares (archived)
var fs = require('fs'),
http = require('http'),
httpProxy = require('http-proxy'),
logger = function() {
// This will only run once
var logFile = fs.createWriteStream('./requests.log');
return function (request, response, next) {
// This will run on each request.
logFile.write(JSON.stringify(request.headers, true, 2));
next();
}
}
httpProxy.createServer(
logger(), // <-- Here is all the magic
{
hostnameOnly: true,
router: {
'example1.com': '127.0.0.1:8001', // server on localhost:8001
'example2.com': '127.0.0.1:8002' // server 2 on localhost:8002
}
}).listen(8000);
I am not sure if this helps because the posted information are really short.
But I found a post that they updated the api ...
you might want to check out this post:
Updating to node-http-proxy v0.5.0
http://blog.nodejitsu.com/updating-node-http-proxy
I done like logging the request headers object on the event proxyReq
const http = require('http'),
httpProxy = require('http-proxy'),
fs = require('fs');
const proxy = httpProxy.createProxyServer({});
const logFile = fs.createWriteStream('./requests.log');
proxy.on('proxyReq', function (proxyReq, req, res, options) {
//Log incoming request headers
logFile.write(JSON.stringify(req.headers, true, 2));
});
const server = http.createServer(function (req, res) {
proxy.web(req, res, {
changeOrigin: true,
target: 'example1.com'
});
});
console.log("listening on port 5050")
server.listen(5050);