How to use rest api in client side? - javascript

Hello today I have simple code Nodejs express that work as rest api. It work when i use postman to send request as get method like code below. But i try use it in client. it doesn't work . So can you help find mistake,please?
// simple rest api
router.get('/getuser', function(req, res, next) {
var connection = getcon();
res.setHeader('Content-Type', 'application/json');
connection.query('SELECT username,password from tbuser', function (error, results, fields) {
if (error) throw error;
console.log('Object : ', JSON.stringify(results));
res.send(JSON.stringify(results));
});
connection.end();
});
// client code
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http.get("http://localhost:3000/users/getuser")
.then(function(response) {
$scope.myWelcome = response.data;
});
});
</script>

It seems like you supply incorrect URL in the client script.
Based on your nodejs code URL must be http://localhost:3000/getuser
UPDATE
You end your connection before you send results. Just move connection.end() inside your callback
if (error) throw error;
console.log('Object : ', JSON.stringify(results));
res.send(JSON.stringify(results));
connection.end();
});

You need to enable Cross-Origin Resource Sharing, a mechanism gives web servers cross-domain access controls, which enable secure cross-domain data transfers. Add this before your router:
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-Headers', 'X-Signature');
res.setHeader('Access-Control-Allow-Headers', 'X-Key');
next();
}
);

Related

How to Form Authentication Header for Axios Request to Node.js App Using Passport Local Authentication?

I have a node.js app and am developing a separate single page app (that will eventually be converted into Android and iOS native apps). I'm setting up an API on the node.js app and am struggling with authentication. The node.js app is using passport-local-mongoose for authentication and I store user data in a MongoDB backend. For testing/dev, the single page app is running on http://localhost:1234/.
My endpoint looks like:
exports.getDevicesAPI = async (req, res) => {
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET, POST');
res.header('Access-Control-Allow-Headers: Authorization');
const devices = await Device.find({ owner: req.user._id });
res.json(devices);
};
I can GET this no problem with something like:
const axios = require('axios');
const url = 'http://localhost:7777/api/devices';
function getDevices() {
axios
.get(url)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
}
I want to add authenticate = passport.authenticate('header', {session: false, failWithError: true}); on the server side to provide authentication, but the following gives me Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:7777/api/devices. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing):
const axios = require('axios');
const url = 'http://localhost:7777/api/devices';
const username = myUsername;
const password = myPassword;
const axiosConfig = {
headers: {
'Content-Type': 'application/json',
},
Authorization: {
username,
password,
},
};
function authenticate() {
axios
.post(url, axiosConfig)
.then(function(response) {
console.log('Authenticated');
})
.catch(function(error) {
console.log('Error on Authentication');
});
}
Routes (for testing):
router.get('/api/devices', catchErrors(deviceController.getDevicesAPI));
router.post('/api/devices', catchErrors(deviceController.getDevicesAPI));
What am I missing?
You are having issues with CORS(Cross-Origin Resource Sharing) Restrictions. Read more about CORS here.
I believe this part of your code is meant to handle the CORS:
exports.getDevicesAPI = async (req, res) => {
// ...
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET, POST');
res.header('Access-Control-Allow-Headers: Authorization');
// ...
};
However, the mistake here is that the setting of these CORS headers is tied to a route, i.e the getDevicesAPI route which is not supposed to be. For requests that are likely to modify resources in another origin(e.g the POST to getDevicesAPI route), the browser would first send a preflight request with the OPTIONS Http method before sending the actual request, the response to the preflight request is where the necessary CORS response-headers is expected to be set. You can find explanations on preflight requests here.
I would typically add a middleware like this above the other routes:
router.all('*', (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', '*');
next();
});

CORS issue on socket.io

I am trying to learn socket.io from this tutorial here. But the problem is I can't make the app run. This is the error I am getting:
XMLHttpRequest cannot load
http://127.0.0.1:3000/socket.io/?EIO=3&transport=polling&t=LZFI7Tq. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost' is therefore not allowed access.
The response had HTTP status code 404.
This is the server side connection
var io = require('socket.io');
var socket = io.listen(3000, '127.0.0.1');
// all the people that have joined the chat
var people = {};
socket.on('connection', function (client) {
console.log('An user connected');
client.on('join', function(name) {
people[client.id] = name;
// client.emit() will only update the client that you are looking
// at, whereas socket.sockets.emti() will update all connected clients
client.emit('update', 'You have successfully connected..');
socket.sockets.emit('update', name + " has joined the conversation..");
socket.sockets.emit('update-people', people);
});
client.on('send', function(msg){
socket.sockets.emit('chat', people[client.id], msg);
});
client.on('disconnect', function() {
socket.sockets.emit('update', people[client.id] + ' has left the conversation..');
delete people[client.id];
socket.sockets.emit('update-people', people);
});
});
And this is the client side connection
var socket = io.connect('http://127.0.0.1:3000');
I have gone through several posts related to this issue but cant solve it. Please help me.
Add this middle-ware on the server where your cookies are created
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-Type');
res.header('Access-Control-Allow-Credentials', 'true');
next();
})

Missing Authorization header when send http request from browser

I have an application in nodejs with jwt authorization, when I send a get from posman the authentication header is found but when I send it from the browser, the authorization header is missing.
Here is the node code, I'm trying to get the authorization header in the verifyToken method, but is not there:
'use strict';
var SwaggerExpress = require('swagger-express-mw');
var app = require('express')();
module.exports = app; // for testing
var _ = require('lodash');
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var config = {
appRoot: __dirname // required config
};
app.set('superSecret', config.secret); // secret variable
// bootstrap database connection and save it in express context
app.set("models", require("./api/model"));
var a = app.get("models").Role;
var repositoryFactory = require("./api/repository/RepositoryFactory").init(app);
var verifyToken = function (req, res, next) {
// verify token and read user from DB
// var token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiTm9tYnJlVXN1YXJpbyI6ImQiLCJQYXNzd29yZCI6IiQyYSQxMCRYS3BJM2ZDRVFoSzVKUFBQWEdIVVZPbUVPQTZsRVRoZDRtWHl4a0tDeGtUcEhvY0U0UTNILiIsImNyZWF0ZWRBdCI6IjIwMTYtMDktMDVUMTg6Mjk6MTYuMDAwWiIsInVwZGF0ZWRBdCI6IjIwMTYtMDktMDVUMTg6Mjk6MTYuMDAwWiIsInByb2Zlc2lvbmFsSWQiOm51bGwsInByb2Zlc2lvbmFsIjpudWxsLCJpYXQiOjE0NzMyNTczMjcsImV4cCI6MTQ3MzI5MzMyN30.CKB-GiuvwJsDAVnKsWb1FktI9tJY57lSgPRVEfW3pts';
var token = req.headers.authorization;
jwt.verify(token, 'shhhhh', function (err, decoded) {
if (err) {
res.status(403).json({ success: false, message: 'Failed to authenticate token.' });
} else {
// if everything is good, save to request for use in other routes
req.user = decoded;
next();
}
});
};
SwaggerExpress.create(config, function (err, swaggerExpress) {
if (err) { throw err; }
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-CSRF-Token, X-Requested-With, Origin, client-security-token, X-Requested-With, Content-Type, Accept, Authorization");
res.setHeader('Content-Type', 'application/json');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.use(verifyToken);
// install middleware
swaggerExpress.register(app);
var port = process.env.PORT || 10010;
app.listen(port);
});
I don't know what configuration I'm missing.
The issue was that I was trying to get the authorization token from the OPTIONS method, this method is sent before the actual get, port, put etc, when is a CORS request. So I was trying to get the authorization header from it and it was not there and the method failed.
The solution was to set in the verify token method a validation like this:
if (req.method !== OPTIONS){
}
I think it is easier if you can change the code in verifyToken function : var token = req.headers.authorization; become var token = req.headers.authorization || req.query.access_token || req.body.access_token;
So in the browser, you can add token in "access_token" query param to authenticate in server instead of setting the header.
Hope it is helpful for you !
You need to set those headers in your browser, try use this chrome plugin called ModHeader https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj
Try adding the following code in .htaccess. Apache removes the Authorization Header. This will ensure it is not removed.
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

CORS Error: Angular.JS, Node.JS and Express [duplicate]

This question already has answers here:
Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
(36 answers)
Closed 7 years ago.
Having issues getting data back from a http post request to an API I've been building. Throws the error:
XMLHttpRequest cannot load (URL to API here). No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:9000' is therefore not allowed
access.
Here's the Angular code on the client side:
$http.post('MyAPIsURLHere', {
date: $scope.information.PubDate
})
.then(console.log)
.catch(console.error);
And here's the Node server side code for my API:
app.post('/getThing', (req, res) => {
const date = req.body.date;
const query = Overquery
const query2 = "alter session set nls_date_format = 'MM/dd/yyyy'";
oracleDB.execute(query2, (err, result) => {
if(err) {
console.error(err);
}
else {
console.log(result);
}
});
oracleDB.execute(query, (err, result) => {
if(err) {
console.error(err);
}
else {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'POST');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.json(result.rows);
}
});
});
First time building an API so any suggestions and help would be greatly appreciated!
Run the following in your project from a bash shell:
npm install cors --save
It will install this:
https://github.com/expressjs/cors
Then add this to your server when creating the app.
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
Edit: This will enable CORS for every domain wich is not recomended for security reasons. Check here for further CORS configuration: https://github.com/expressjs/cors#configuring-cors
In your node application, this sample of code should solve your issues:
// Allowing X-domain request
var allowCrossDomain = function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Cache-Control");
// intercept OPTIONS method
if ('OPTIONS' == req.method) {
res.send(200);
}
else {
next();
}
};
app.use(allowCrossDomain);

Post request from Backbone client to NodeJS service

Somehow I am not able to send data from Backbone model to NodeJS service.
Backbone Model
var Money = Backbone.Model.extend({
url: 'http://localhost:3000/sendCoins',
defaults: {
fromAddress: "",
toAddress: "",
amount: ""
},
transferMoney: function(req, resp) {
//get field values
console.log(req.fromAddress); //prints fine
this.save();
}
});
var transferMoney = new Money();
Node JS service
var app = express();
app.listen(3000);
app.use(express.json());
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
app.post('/sendCoins', function(req, res) {
console.log(req.body.toAddress);
console.log(JSON.stringify(req.body));
console.log(req.body.amount);
});
When I post the request from backbone view console.log(JSON.stringify(req.body)); prints {"fromAddress":"","toAddress":"","amount":""}.
As mentionned by M Omary, you need to use the body parser in order to have access to req.body. Add the following code above app.post to see if it works:
app.use(express.bodyParser());

Categories