CORS Problem when using two express application - javascript

I'm trying to use two Node.js express servers on a Windows Server 2012, each one with a different FQDN (example1.b.br | exemple2.b.br).
The applications are two Watson Chatbots, so both of them need to use route /conversation to communicate with IBM.
One chatbot uses port 443 and the other one use 8443.
The problem is: Each one of them are in different directories and have their own subdirectory called 'public', but when I execute both servers, the one using port 8443 uses the port 443 server's 'public' subdirectory.
Chatbots
certificates
Chatbot1
node_modules
public
css
script
Chatbot2
node_modules
public
css
script
Chatbot1 app.js:
const AssistantV1 = require('watson-developer-cloud/assistant/v1');
const express = require('express');
const bodyParser = require('body-parser');
const http = require('http');
const https = require('https');
var fs = require('fs');
var httpApp = express();
var workspace;
var options = {
key: fs.readFileSync('certificates/key.pem'),
cert: fs.readFileSync('certificates/server.crt')
};
const app = express();
app.use(bodyParser.json());
app.use(express.static('./public'));
const port = 80;
const httpsPort = 8443;
httpApp.set('port', process.env.PORT || 80);
const assistant = new AssistantV1({
username: 'XXXXX',
password: 'XXXXX',
url: 'https://gateway.watsonplatform.net/assistant/api/',
version: '2018-02-16'
});
workspace = 'XXXXXXX';
app.post('/conversation/', (req, res) => {
const { text, context = {} } = req.body;
const params = {
input: { text },
workspace_id: workspace,
context,
};
assistant.message(params, (err, response) => {
if (err) res.status(500).json(err);
res.json(response);
});
});
try{
//var httpServer = http.createServer(httpApp, app).listen(port);
var httpsServer = https.createServer(options, app).listen(httpsPort);
//httpServer.listen(port, () => console.log(`Running on port ${port}`));
httpsServer.listen(httpsPort, 'exemple1.b.br', () => console.log(`HTTPS Running on port ${httpsPort}`));
console.log(`---------------------------------`);
console.log(`-----------ROBO INICIADO---------`);
console.log(`---------------------------------`);
}catch(err){
console.log(`*********************************`);
console.log(`*****Falha ao iniciar o Robo*****`);
console.log(`*********************************`);
console.log(err);
} */
Chatbot2 app.js:
const AssistantV1 = require('watson-developer-cloud/assistant/v1');
const express = require('express');
const bodyParser = require('body-parser');
const http = require('http');
const https = require('https');
var fs = require('fs');
var httpApp = express();
var workspace;
var options = {
key: fs.readFileSync('certificates/key.pem'),
cert: fs.readFileSync('certificates/server.crt')
};
const app = express();
app.use(bodyParser.json());
app.use(express.static('./public'));
const port = 80;
const httpsPort = 443;
httpApp.set('port', process.env.PORT || 80);
const assistant = new AssistantV1({
username: 'xxxxxxx',
password: 'xxxxxx',
url: 'https://gateway.watsonplatform.net/assistant/api/',
version: '2018-02-16'
});
workspace = 'XXXXXXX'
app.post('/conversation/', (req, res) => {
const { text, context = {} } = req.body;
const params = {
input: { text },
workspace_id: workspace,
context,
};
assistant.message(params, (err, response) => {
if (err) res.status(500).json(err);
res.json(response);
});
});
try{
var httpsServer = https.createServer(options, app).listen(httpsPort);
httpsServer.listen(httpsPort, 'exemple2.b.br', () => console.log(`HTTPS Running on port ${httpsPort}`));
console.log(`---------------------------------`);
console.log(`-----------ROBO INICIADO---------`);
console.log(`---------------------------------`);
}catch(err){
console.log(`*********************************`);
console.log(`*****Falha ao iniciar o Robo*****`);
console.log(`*********************************`);
}
How can I "force" the server to use its own subdirectory?

"Problem" solved.
Actually, it was my lack of study about how FQDN actually works and a little to blame on Anti-virus.
example2.b.br don't need the ":443" on its url, because the port is default for HTTPS.
But when I use example1.b.br, it needs ":8443" after (https://example1.b.br:8443).
At least this simple mistake make me learn about this detail.
After that, I discovered that the server anti-virus were blocking some files. After creating an exception on the port to communicate only through intranet, the problem got solved.

Related

socket.io application keeps loading

Why does my socket.io webapplication keeps loading, i've implemented auth with certifications, but when i try to access localhost, it keeps loading. ive tried follow this doc, but dosent help:https://socket.io/docs/v3/client-initialization/
i dont get any error.
server.s
'use strict';
// Setup basic express server
var express = require('express');
var app = express();
var port = process.env.PORT || 4000;
var crypto = require('crypto');
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('./data/db.sqlite');
const bcrypt = require('bcrypt');
const tls = require('tls');
var validator = require('validator');
// Routing
app.use(express.static(__dirname + '/public'));
app.use(express.json());
// Chatroom
// usernames which are currently connected to the chat
var usernames = {};
var numUsers = 0;
const fs = require("fs");
const server = require("https").createServer({
cert: fs.readFileSync("./server-cert.pem"),
key: fs.readFileSync("./server-key.pem")
});
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
const io = require("socket.io")(server);
io.on('connection', function (socket) {
console.log("works")
}
client.js
const fs = require("fs");
const socket = require("socket.io-client")(4000, {
ca: fs.readFileSync("./server-cert.pem")
});
socket.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});

Trying to run express node js as https server but it won't run

I'm trying to get HTTPS working on express.js for node, and it won't run.
This is my server.js code.
const fs = require('fs');
const http = require ('http');
const https = require('https');
const options = {
pfx: fs.readFileSync('ssl/pfxfile.pfx'),
passphrase: 'password'
};
const express = require('express');
const app = express();
const path = require('path');
app.use(express.json());
app.use(express.static("express"));
app.use('/', function(req,res){
res.sendFile(path.join(__dirname+'/express/index.html'));
});
var httpServer = http.createServer(app);
var httpsServer = https.createServer(options, app);
httpServer.listen(8080);
httpsServer.listen(8443);
When I run it reports no errors but it just get stuck to nothing (I waited 30 minutes to see if it does something and nothing happened).
httpServer.listen(8080, ()=>{console.log('Server is running')});
If the server successfully started, it should output "Server is running" in the console. This is a nice way to check if the server is working as intended.
I found my error, thanks for your answers, it's been helping me, my error was first that I didn't put any console.log and the second was that I was not typing 8443 in the browser.
const fs = require('fs');
const http = require('http');
const https = require('https');
const options = {
pfx: fs.readFileSync('ssl/pfxfile.pfx'),
passphrase: 'password'
};
const express = require('express');
const app = express();
const path = require('path');
app.use(express.json());
app.use(express.static("express"));
app.use('/', function(req,res){
res.sendFile(path.join(__dirname+'/express/index.html'));
});
const httpServer = http.createServer(app);
const port = process.env.PORT || 8080;
const httpsServer = https.createServer(options, app);
const portHttps = process.env.PORT || 8443;
httpServer.listen(port, () => console.log('Http listening on port ' + port));
httpsServer.listen(portHttps, () => console.log('Https listening on port ' + portHttps));

Express-session on two servers

I've been trying to use express-session on two local servers.
The first server is for manipulating the database and the second is for loading pages.
I want to save some data in the session from the first server and use it in the second server.
Here's the code of the first API
require("dotenv").config();
const express = require('express');
const mysql = require("mysql");
const crypto = require("crypto");
const cors = require("cors");
const apiApp = express();
apiApp.use(express.json());
apiApp.use(cors());
const pool = mysql.createPool({
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
host: "localhost"
});
var algorithm = 'aes256'; // algorithm
var key = 'password';
apiApp.post('/api/Connexion', (req, res) => {
let cipheriv = crypto.createCipher(algorithm, key);
let encryptedPassword = cipheriv.update(req.body.motDePasse, 'utf8', 'hex') + cipheriv.final('hex');
var data = [req.body.courriel, encryptedPassword];
const query = "SELECT * FROM utilisateurs WHERE courriel=? AND motDePasse=?";
pool.query(query, data, (error, results) => {
if (results[0] && !error) {
res.send(true);
req.session.courriel = req.body.courriel;
} else {
res.send(false);
}
});
});
module.exports = apiApp;
And the second
require("dotenv").config();
const express = require('express');
const cors = require("cors");
const path = require("path");
const coreApp = express();
coreApp.use(express.json());
coreApp.use(cors());
let dir = path.resolve(__dirname, '..', '..') + '/'
coreApp.use(express.static(dir));
coreApp.get('/connexion', (req, res) => {
if (req.session != undefined) {
console.log(req.session.courriel);
}
res.sendFile(dir + "index.html");
});
coreApp.get('/application', (req, res) => {
res.sendFile(dir + "application.html");
});
coreApp.get('/:a', (req, res) => {
res.redirect("/");
});
module.exports = coreApp;
So, I am trying to set the session variable at line 64 of the first code and use it at line 17 of the second code.
How can I do it ?
Thanks !
You can share session data between servers if you use a shared database as the session store for express-session, often redis, but any database can work as long as both servers access the same database for express-session storage and express-session is configured properly.
There are express-session storage providers for dozens of databases, including express-mysql-session that works with the database that you're already using.

Respond to client after receiving client to server POST request (Node.JS)

I have been attempting to respond to a client-side request with Node.JS. I have discovered Node JS - call function on server from client javascript, which seems to explain what I want, except that I can't seem to translate it to my program.
Here is the request via POST in index.html:
$.post("/", {data: 'hi'}, function(result){
$("body").html(result);
});
what I was hoping it would do would be write the result of the call, from my server.js (Node):
const express = require('express');
const path = require('path');
const http = require('http');
const fs = require('fs');
function handler(data, app){
if(req.method == "POST"){
app.setHeader('Content-Type', 'text/html');
app.writeHead(200);
app.end(data);
}
}
const BUILDPATH = path.join(__dirname);
const { PORT = 3000 } = process.env;
const app = express();
app.set('port', PORT);
app.use(express.static(BUILDPATH));
app.get('/*', (req, res) => res.sendFile('static/index.html', { root: BUILDPATH }));
const httpServer = http.createServer(app);
httpServer.listen(PORT);
console.info(`🚀 Client Running on: http://localhost:${PORT}`);
try this code:
const express = require('express');
const path = require('path');
const http = require('http');
const fs = require('fs');
function handler(data, app){
if(req.method == "POST"){
app.setHeader('Content-Type', 'text/html');
app.writeHead(200);
app.end(data);
}
}
const BUILDPATH = path.join(__dirname);
const { PORT = 3000 } = process.env;
const app = express();
app.set('port', PORT);
app.use(express.static(BUILDPATH));
app.get('/', (req, res) => {
res
// best practice is to always return an status code
.status(200)
// just return an json object
.json({"msg": "ok, it all works just fine"})
});
const httpServer = http.createServer(app);
httpServer.listen(PORT);
console.info(`🚀 Client Running on: http://localhost:${PORT}`);
The issue is, is that the only route your Node server listens to is the one you define with /*. As you can see, that route returns your index.html file to the client. You did not specify a route that listens for a request that comes from the client.
To solve the issue, you will have to define a route that listens on a specific route for the request you are trying to make from your client.
I see you are using ExpressJS. here is the documentation on writing routes.

Enabling HTTPS on an express server

I'm trying to configure my express server to use HTTPS but I am running into some issues. I followed the documentation to setup my HTTPS server but I am still encountering some errors.
Here's my app.js
var express = require('express');
var app = express();
var server = require('https').createServer(options, app);
var io = require('socket.io')(server);
var port = process.env.PORT || 3000;
var fs = require('fs');
var options = {
key: fs.readFileSync('/test/key.pem'),
cert: fs.readFileSync('/test/cert.pem')
};
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
When starting my server I encounter
https.js:32
if (process.features.tls_npn && !opts.NPNProtocols) {
^
TypeError: Cannot read property 'NPNProtocols' of undefined
at new Server (https.js:32:40)
at Object.exports.createServer (https.js:56:10)
So, I tried to define NPNProtocols within options, but that did not work. Anyone have any pointers here?
Thank you.
try this once, i think you should have certificate in .crt format. and you will require tls module.
var sslOptions = {
key: fs.readFileSync('public/server.key'),
cert: fs.readFileSync('public/server.crt')
};
tls.createServer(sslOptions, function (cleartextStream) {
var cleartextRequest = net.connect({
port: port,
host: serverStr
}, function () {
cleartextStream.pipe(cleartextRequest);
cleartextRequest.pipe(cleartextStream);
});
}).listen(443);
port is you http port . and sercerStr is you server address.
IMO, the issue is not with the extension of the keys, rather the ssl configuration used. Use https node module with correct ssl options for ca, cert, and key to enable https with express.
// server/index.js
const express = require('express');
const fse = require('fs-extra');
const helmet = require('helmet');
const https = require('https');
const path = require('path');
// path to cert files
const paths = {
certFile: '/path/to/cert.pem',
chainFile: '/path/to/fullchain.pem',
privateFile: '/path/to/privkey.pem',
};
/* Express implementation (ignore) */
const app = express();
app.use(helmet());
app.use(express.static(path.join(__dirname, '..')));
app.get('/', (request, response) => {
response.sendFile(path.join('index.html'));
});
// setup https
const setupHttps = () => {
const promises = [
fse.readFile(paths.chainFile),
fse.readFile(paths.privateFile),
fse.readFile(paths.certFile),
];
return Promise
.all(promises)
.then(data => {
const [ chainData, privateData, certData ] = data;
const options = {
ca: chainData.toString('utf-8'),
cert: certData.toString('utf-8'),
key: privateData.toString('utf-8'),
};
return https.createServer(
options,
app
).listen(443);
})
.catch(err => console.log(err));
};
return setupHttps();
EDIT: I used helmetjs for better security with http headers.

Categories