feathersjs -> socketio https request not working - https

I have an application made in featherjs which I would like to run with https. I have gotten that working. I did that by changing the 'index.js' file to look like this:
const fs = require('fs');
const https = require('https');
const app = require('./app');
const port = app.get('port');
const host = app.get('host');
//const server = app.listen(port);
const server = https.createServer({
key: fs.readFileSync('./certs/aex007.key'),
cert: fs.readFileSync('./certs/aex007.crt')
}, app).listen(port, function(){
console.log("Mfp Backend started: https://" + host + ":" + port);
});
As soon as I now go to e.g. 'https://127.0.0.1/a_service_name' in postman, I get a result after accepting the certificate. When I go to the address in a browser it also give result, the certificate indication is 'red' for it's selfsigned.
So my problem is the following. When I go to 'http://127.0.01' in a browser, in stead of the 'index.html' file I get nothing of my 'socket' information, only a blank page. I get the following error in the console
info: (404) Route: /socket.io/?EIO=3&transport=polling&t=LwydYAw -
Page not found
Then 'index.html' file I'm using is currently containing this:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script type="text/javascript" src="//cdn.rawgit.com/feathersjs/feathers-client/v1.1.0/dist/feathers.js"></script>
<script type="text/javascript">
var socket = io('https://127.0.0.1:3001');
var client = feathers()
.configure(feathers.hooks())
.configure(feathers.socketio(socket));
var todoService = client.service('/some_service');
todoService.on('created', function(todo) {
alert('created');
console.log('Someone created a todo', todo);
});
</script>
Can someone explain to me what to do to get the alert message?
Edit 2017/09/27
I found on the internet that socket.io is configured like
var https = require('https'),
fs = require('fs');
var options = {
key: fs.readFileSync('ssl/server.key'),
cert: fs.readFileSync('ssl/server.crt'),
ca: fs.readFileSync('ssl/ca.crt')
};
var app = https.createServer(options);
io = require('socket.io').listen(app); //socket.io server listens to https connections
app.listen(8895, "0.0.0.0");
However the require of feathers-socket.io is in the app.js not the index.js. I wonder if I can move that?

As daffl pointed out on the feathers slack channel here; check out the documentation which requires in feathers-socketio explicitly before calling configure on the app, in addition to the https portion of the docs. Putting those two together, I would do something like this (untested):
const feathers = require('feathers');
const socketio = require('feathers-socketio');
const fs = require('fs');
const https = require('https');
const app = feathers();
app.configure(socketio());
const opts = {
key: fs.readFileSync('privatekey.pem'),
cert: fs.readFileSync('certificate.pem')
};
const server = https.createServer(opts, app).listen(443);
// magic sauce! Socket w/ ssl
app.setup(server);
The structure of your app.js and index.js is totally up to you. You can do all of the above in a single file as shown, or split out the https/fs requires into index.js, and configuring the app into app.js - I would recommend this approach because it will allow you to change the (usually smaller) index.js file if you every decide to use a reverse proxy like nginx to handle ssl instead of node.

Related

Configuring socket.io on Cloud Foundry

I'm trying to set up a socket.io connection on Cloud Foundry via IBM Toolchains. I've gone through the docs and have been trying to get socket.io to connect to port 4443. I'm kind of new to this so would appreciate if you could provide some pointers on how to set up socket.io on the CF env as I still struggle to digest parts of the documentation. Code can be found below.
//---------------------------
// app.js
//---------------------------
// Start the app on cloud foundry
var express = require('express');
var app = express();
var cfenv = require('cfenv');
var appEnv = cfenv.getAppEnv();
app.use(express.static(__dirname + '/public'));
app.listen(appEnv.port, '0.0.0.0', function() {
console.log("Server is starting on " + appEnv.url);
});
// Connect socket.io
var server = require('http').Server(app);
var io = require('socket.io')(server);
var cookieParser = require('cookie-parser');
app.get('/', function (req, res) {
res.sendFile(__dirname + 'public/index.html');
});
io.on('connection', function (socket) {
console.log('a user connected');
});
var port = 4443; // Cloud Foundry assigned port for TCP/WebSocket communications
server.listen(port, function() {
console.log('listening on ', port);
});
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect("https://0.0.0.0:4443");
</script>
My understanding after going through the socket.io docs is that the IP provided should be the location.hostname which I believe to be 0.0.0.0 in this case as it refers to the IP which the express instance for the app is listening on. Not too sure about this though.
By changing it to below:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.slim.js"></script>
<script> var socket = io(); </script>
The error changes to a 404 error with the following error being repeated: "https://realtimetrafficanalysisaks.mybluemix.net/socket.io/?EIO=3&transport=polling&t=". I've checked regarding the app and server settings but can't seem to pinpoint the error
Thanks in advance!
I didn't manage to sort this out with socket.io due to the port issue but I was able to get it running using the express-ws package

how socket.io get downloaded from my server even I didn't assign any router for it

how nodejs handle /socket/socket.io.js/ request even I don't assigned any router for it
this is script tag in html
<script src="/socket.io/socket.io.js"></script>
and this is my simple nodejs server
var express = require('express');
var path = require('path');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var port = 8080;
app.use(express.static(path.join(__dirname, "public")));
server.listen(port, function() {
console.log("Listening on port " + port);
});
it should get this error : 404 page not found
but it correctly load it
It's the default behaviour of socket.io server .
take a look here: https://socket.io/docs/server-api/
it's called "serveClient" and it's set to true as default .

Local Parse Server throwing 'unauthorised' despite correct keys

I'm setting up a local Parse Server: https://github.com/ParsePlatform/parse-server
I'm setting my keys as per the link above yet still getting 'Unauthorised'. Any ideas why this is?
Here's the snippet where I create the server var:
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var app = express();
var port = process.env.PORT || 1337;
// Specify the connection string for your mongodb database
// and the location to your Parse cloud code
var api = new ParseServer({
databaseURI: 'mongodb://localhost:27017',
cloud: '/Users/jack/Desktop/dev/node_modules/parse-server/lib/cloud/main.js', // Provide an absolute path
appId: 'jack1234',
masterKey: 'jack1234',
serverURL: 'http://localhost:' + port + '/parse'
});
// Serve the Parse API on the /parse URL prefix
app.use('/parse', api);
// Hello world
app.get('/', function(req, res) {
res.status(200).send('Express is running here.');
});
app.listen(port, function() {
console.log('parse-server-example running on port ' + port + '.');
});
Here's a screenshot of the Unauthorised:
You need to wirte the value in the header without '' (Apostrophe).
like:
X-Parse-Application-Id : jack1234
I think the issue might be from the headers you are sending to the ending. this is why you get the 403 code. I'm guessing the server does not recognize requests with these headers.
// Serve the Parse API on the /parse URL prefix
app.use('/parse', api);
On this line shown above you are injecting the arguments in which the express app needs to be authenticated with. So why not just make a request to it without the Headers ?

Connecting socket.io client to https

I'm trying to build a web chat application and want to connect my client to the socket.io server with https.
Seems like everything's fine, but the client is not connecting after all..
Server Code:
var app = require('express')();
var fs = require('fs');
var options = {
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.crt')
};
var server = require('https').createServer(options, app).listen(3000,function(){
console.log("Https server started on port 3000");
});
var io = require('socket.io').listen(server);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log("Client connected");
/*....*/
});
Client code to connect to server:
$(function($){
var socket = io.connect('https://localhost:3000', {secure: true});
.....
});
It kind of doesn't run the code inside of $(function($)..
When I make it a http server it works just fine..
Simply
var socket = io.connect('/', {secure: true});
EDIT: By default socket.io will try to establish a connection on the same host as webserver hosts web content, so no need to specifying host/protocol/port. The / states to connect to default namespace.
I solved the problem..
So for http it was enough if you begin your script on the client with
$(function(){
....
});
But it wouldn't work with https.
I changed it to
jQuery(function($){
....
})(jQuery);
Pretty odd but it worked for me.

HTTPS express.js server and routes

I just changed my server to use HTTPS. I have a very boiler plate code. When I go to localhost:8888, the browser hangs and my route never gets called. Curl from the command line is the same.
I am wondering I am defining my route incorrectly.
THe code is the following:
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var https = require('https');
var path = require('path');
var app = express();
var fs = require('fs');
// all environments
app.set('port', process.env.PORT || 8888);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.methodOverride());
app.use(app.router);
//app.use(logErrors);
app.use(express.static(path.join(__dirname, 'public')));
var options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')};
app.get('/', routes.index);
app.get('/users', user.list);
https.createServer(options, app.handle).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Anyone sees what the issue is?
I think you want just app where you have app.handle:
https.createServer(options, app)....
Also note for cURL testing you'll need to do curl --insecure https://localhost:8888 since you are presumably using a non-commercial self-signed certificate which neither curl nor browsers will trust without a user explicit override.
You need to go to https://localhost:8888.
The browser can't automatically figure out that you're listening for SSL connections on that port.

Resources