Node express request body undefined on AWS Lambda - javascript

Im using AWS Amplify to generate Node Express rest API endpoints.
I recently added a new endpoint, but I keep getting undefined in the request body, and I can't figure out where I might have miss-configured my application.
App.js
var express = require("express");
var bodyParser = require("body-parser");
var awsServerlessExpressMiddleware = require("aws-serverless-express/middleware");
// declare a new express app
var app = express();
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
app.use(awsServerlessExpressMiddleware.eventContext());
// Enable CORS for all methods
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"
);
next();
});
var aws = require("aws-sdk");
const https = require("https");
app.post("/refresh", function(req, res){
console.log(JSON.stringify(req.body));
// {}
console.log(JSON.parse(req.body));
//Error: unexpected token o in JSON at position 1
});
I'm testing this in the AWS console with this payload
{
"path": "/refresh",
"httpMethod": "POST",
"header": "{\"content-Type\":\"application/json\"}",
"body": "{\"Username\":\"test\"}"
}

Set header as
"Content-Type: application/json"

Related

CORS: Access-Control-Allow-Origin not working in Node.js

I am trying to send ajax post request from my rails app (https://myrails.app.com) to my node js app (https://mynodejs.app)
Below are the contents of my app.js file
const express = require('express');
const app = express();
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "https://myrails.app.com");
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
if('options' == req.method()){
res.status(200);
}else{
next();
}
});
require('./middlewares/middleware')(app);
process.on('uncaughtException', (ex) => {
console.log(ex.message);
process.exit(1);
});
module.exports = app;
below is my server.js file
const serverProtocol = ['production', 'staging'].includes(process.env.NODE_ENV) ? require('http') : require('https');
const app = require('./app');
const port = process.env.PORT || 3002;
const server = serverProtocol.createServer(app);
server.listen(port);
I still get an error on my rails app, this is what i see in my browser console
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://mynodejs.app (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)
Any help on how to fix this would be really great. Thanks.

Redirect Url not working and getting No 'Access-Control-Allow-Origin' header Error

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);
...

socket.io not found when calling server

I'm trying to connect socket.io on Angular and Nodejs server
In Angular I have declared a new socket and connect it
import * as io from 'socket.io-client';
...
#component
...
const socket = io.connect('http://localhost:3000');
In back end : server.js
const express = require('express');
const app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.set('origins', 'http://localhost:4200');
var routes = require('./routes/routes')(io);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:4200");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT ,DELETE");
res.header('Access-Control-Allow-Credentials', true);
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
});
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
console.log("connectd");
});
app.use('/', routes);
var server = app.listen(3000, function (io) {
})
The app is compiling and getting data from server. but only socket.io is not working
I get this error:
GET http://localhost:3000/socket.io/?EIO=3&transport=polling&t=MEpN9Qy 404 (Not Found)
socket.io is attached to http:
var http = require('http').Server(app);
var io = require('socket.io')(http);
so you have to use:
http.listen(3000)
instead of
app.listen(3000) // This will only start an express server
Your socket server never starts, that's why you're getting a 404, since only express is running.

How to protect a http post from Angular 2 to Express Server

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);

Node.Js error "No 'Access-Control-Allow-Origin' header is present on the requested"

This question is similar to others; however there is a difference that makes it very confusing why it is not working.
My JavaScript was calling 6 json files and all worked correctly. In Node.JS I have cors and headers set up as shown below:
var fs = require('fs');
var http = require("https");
var express = require('express');
var app = express();
var path = require('path');
var http = require("http");
var url = require("url");
var req = require('request')
var pem = require('pem');
var cors = require("cors");
app.use(express.static(path.join(__dirname, '../')));
app.listen(process.env.PORT || 8080);
app.options('*', cors());
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");
next();
});
app.all('/posts', function(req, res){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
});
app.get('/', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.writeHead(200, {'Content-Type': 'text/plain'});
contents = fs.readFileSync("sliderImages.json", "utf8");
console.log(path.join(__dirname, '/sliderImages.json'));
res.end(contents);
});
All 6 json files are grabbed from the absolute URL path by Node JS. I have made 2 more yesterday and everything was working fine. However, today I made one and implemented the same way and received the following error:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
I am implementing each the same way, example:
var base_url = 'http://127.0.0.1:8080';
mainInformationTop();
function mainInformationTop()
{
$.ajax({
type: "GET",
url: base_url + "/api/topInformation.json",
dataType: "json",
success: function(response)
{
var json_obj = response.mainDescription;
var imagesSlider="";
var imagesSliderDescription ="";
for (var i = 0; i< json_obj.length; i++)
{
}
}
,
error: function(jqXHR, textStatus, errorThrown) {
alert(jqXHR.status);
}
})
}
I don't think the json file is relevant but below is my json file:
{"mainDescription":[
{
"display": "my display",
"description" : "my description"
}
]}
I have took out the information in the for loop for testing as well as my append because irrelevant. For some reason it fails and goes to error instead of success. All other calls are set up the same way and work correctly.
This is a much more simple version of this answer which achieves the same effect:
var fs = require('fs');
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
app.use(express.static(path.join(__dirname, '../')));
app.get('/', function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
contents = fs.readFileSync('sliderImages.json', 'utf8');
res.end(contents);
});
app.listen(process.env.PORT || 8080);
Fixed it.
var fs = require('fs');
var http = require("https");
var express = require('express');
var app = express();
var path = require('path');
var http = require("http");
var url = require("url");
var req = require('request')
var pem = require('pem');
var cors = require("cors");
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");
next();
});
app.use(express.static(path.join(__dirname, '../')));
app.listen(process.env.PORT || 8080);
app.options('*', cors());
app.all('/*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:8080");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
next();
});
app.get('/', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.writeHead(200, {'Content-Type': 'text/plain'});
contents = fs.readFileSync("sliderImages.json", "utf8");
console.log(path.join(__dirname, '/sliderImages.json'));
res.end(contents);
});
Despite what the comments said the only real thing I changed was moving the app.use before everything else. This solved the issue.
Install cors
npm install cors --save
Write this code in your app.js
const cors = require('cors');
const express = require('express');
let app = express();
app.use(cors());
app.options('*', cors()); //put this before your route
I also suffer this problem the code was as same as above but we want to put the code in starting point. dont put this code in last that means before (res.end()) sending response to client. Three methods (GET,POST,HEAD) that allowed you when you put this code anywhere i think but for other method try this and try with other modules like cors,express but i used http module only
var server=http.createServer(function (req, res) {
res.setHeader("Access-Control-Allow-Origin","*");
res.setHeader("Access-Control-Allow-Methods","PUT,GET,DELETE,PATCH")
res.setHeader('Access-Control-Allow-Credentials', true)
res.setHeader('Access-Control-Allow-Headers','X-Requested-With,content-type,Origin,Accept,Authorization')
// your other code followes

Categories

Resources