Does node + socketio + express + https secure the socket data as well - node.js

With the following code snippet:
var express = require('express'),
app = express(),
server = require('https').createServer(app),
io = require('socket.io')(server);
app.get('/', function(req, res, next) {
res.sendFile(__dirname + '/assets/html/index.html');
});
/** More routing functions **/
io.on('connection', function(socket) {
components.socket.onConnect(socket, config);
});
io.on('save', function(data){
var saved = save(data);
io.emit('response', saved);
});
/** More Socket.io functions **/
server.listen(443, function() {
console.log("Server Ready.");
});
Assuming this server side setup (with ssl cert) and the clients connect securely, are the data value on save and the saved value emitted back with socket.io also encrypted with the ssl cert like the web data would be too?

The answer is yes as long as you use https for the initial connection. In your example, since you're only ever using https, this will never be a problem for you.

Related

Why do I need to add "require("http")" when I already have express?

I am trying to follow this tutorial on creating a simple chat application using socket.io. I am at the part of the tutorial where I have to insert all of the code below into a js file and initiate it. I just don't understand why the 2nd of code exist, I heard that express can do a lot more than http. Instead of using the "http.listen" code, can't "app.listen" be used and "app" passed to "io" instead?
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Why do I need to add “require(”http“)” when I already have express?
You don't have to manually load the http module yourself. You use express to create an http server for you (it will load the http module for you) and integrate it with socket.io without manually loading the htttp module like this:
const app = require('express')();
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
const server = app.listen(3000, function(){
console.log('listening on *:3000');
});
const io = require('socket.io')(server);
io.on('connection', function(socket){
console.log('a user connected');
});
Internally, app.listen() loads the http module for you, creates a server and then starts it, returning the server object which you can then use with socket.io.
Inside of express, this is the code for app.listen():
const http = require('http');
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
So, somebody had to load the http module. If you use app.listen(), the express will do it for you.
You are right. Express is a framework that sits on top of the nodejs application and provides a much easier,provided more middleware to handle routes, session and cookies and more efficient way to create server as such
var express = require('express');
var app = express();
app.listen(3000);
In this example, for the purpose of creating a socket between different channels, you have to use HTTP to indicate that the socket is used to handle HTTP requests/responses. You simply can't pass an entire express application to io.

Socket.io with Express, emit not working within express route

Either I have a fundamental misunderstanding of how socket.io works (highly likely), or I am just finding some bug that nobody knows about (nearly impossible).
I've been trying to integrate express with socket.io. On the client side, everything works fine: user clicks button, event emits, everybody's happy.
However, let's say I want to emit this event from within an express route before rendering a page. The event never seems to be emitted. From all the questions on this that I've looked at, I'm supposed to be able to simply plug my "io" instance into my app and then access it from within my routes.
So this is my setup...
// index.js
var app = express();
var port = process.env.PORT || 3700
var io = require('socket.io').listen(app.listen(port));
io.on('connection', function (socket) {
console.log("Socket connected on port " + port)
socket.on('send', function (data) {
console.log("WAFFLES")
});
});
console.log('The magic happens on port ' + port);
require('./app/routes.js')(app, io);
// app/routes.js
module.exports = function(app, io){
app.get('/', function(req, res){
io.on('connection', function (socket) {
console.log("Hello from the route!")
socket.emit('send', {message: 'urdum'})
});
res.render('index')
})
}
So in this instance, I want to be able to go into the / route, see "Hello from the route" and then "WAFFLES" logged to the console after emitting the "send" event. Instead I get absolutely nothing.
I've tried to pass in "io" via app.set('socketio', io). But no matter what, nothing works.
I've also tried emitting the event within the route without the io.on('connection') and simply just doing
io.emit('send' ...)
OR
io.sockets.emit('send' ...)
I have a fundamental misunderstanding of how socket.io works (highly likely)
You are right,
This is typical setup for socket-io, read more in https://socket.io/docs/
// index.js
var express = require('express');
var socketio = require('socket.io');
var http = http = require('http');
var app = express();
// Attach Socket.io
var server = http.createServer(app);
var io = socketio.listen(server);
app.set('socketio', io); // <-- bind socket to app
app.set('server', server); // <-- optional
io.on('connection', function (socket) {
console.log("Socket connected on port " + port);
});
app.listen(3000);
server.listen(3001) // <-- socket port
// app.get('server').listen(3001); // <-- use server or app.get('server')
In your router, access socket by req.app.get('socketio');
// app/routes.js
module.exports = function(app, io){
app.get('/', function(req, res){
var socketio = req.app.get('socketio');
socketio.emit('send', {message: 'urdum'});
res.render('index')
})
}

Socket.io doesn't initialize and doesn't connect to the node server on shared hosting

I have installed node.js on my shared hosting with GoDaddy and can run node apps.
I don't exactly know where the problem is, but here's what's going on. I run the server, and it starts listening on a port (I tried a range from 49000 to 56000).
But when the client tries to connect, i.e. access '/' on the server, the node is silent, therefore it doesn't receive any connection requests. So that kind of narrows it down to socket.io.
In the console within a few seconds it spits out this:
socket.io-1.4.5.js:1 GET http://website.com:55872/socket.io/?EIO=3&transport=polling&t=LQRdEP9 net::ERR_CONNECTION_TIMED_OUT
I have tried to source socket.io from the cdn as well as my own directory - nothing.
This is what the server looks like:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
//------------- GLOBAL VARIABLES ---------------
SERVER_PORT = 55872;
connections = [];
//----------------------------------------------
server.listen(SERVER_PORT, "127.0.0.1");
console.log('................................................');
console.log('=> Server is listening on port: ' + SERVER_PORT);
console.log('................................................');
app.get('/', function(req, res){
console.log('=> Loading index.html!');
res.sendFile(__dirname + '/index.html');
});
// ----------- MIDDLEWARE ----------------------
// ----------- CONNECTIONS ---------------------
io.sockets.on('connection', function(socket){
connections.push(socket);
console.log('=> Client connected! Total connected: %s', connections.length);
// Disconnect socket
socket.on('disconnect', function(data){
connections.splice(connections.indexOf(socket), 1);
console.log('=> Client disconnected! Total connected: %s', connections.length);
});
Client:
$(function(){
//--------- SOCKET INIT --------------
var socket = io.connect('http://website.com:55872/');
});
Is the issue with socket.io or the node, or me...?
GoDaddy does not currently support running node.js servers on shared hosting. You would need a VPS account. GoDaddy did buy Nodejitsu so presumably they will be expanding their node.js offerings, but as of this moment you can't run node.js servers on GoDaddy shared hosting.
I had similar problems getting socket.io to work with express. Here is a snippet from my working server code:
var express = require('express');
var app = express();
app.get('/', function(req, res) {
// to allow cross-origin requests
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
//...
});
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(process.env.PORT, process.env.IP, function() {
console.log("Listening!");
});
io.on('connection', function (socket) {
console.log("Got connection!");
//...
});
It's slightly different from what you have, and may do the trick. Otherwise, your problem probably isn't with the node.js code.
This was hosted on a free Cloud9 workspace. I've also had node servers on Heroku... you should try one of those platforms, as they have official support for node.

nodejs can't work with SSL

Im trying to run nodejs app to work with my php project. the problem is I think with SSL which is enabled in the server.
I have two files that I found in my root directory after SSL install: domain.com.csr and domain.com.key and I tried to combine them to connection while creating https server, but nothing worked for me.
so far I have this code:
var socket = require('socket.io');
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
var io = socket.listen(server);
app.get('/test', function(req, res) {
res.send('hello world');
console.log('visited test')
});
io.sockets.on('connection', function (client) {
console.log("New client !");
client.on('message', function (data) {
console.log('Message received ' + data.name + ":" + data.message);
io.sockets.emit('message', {name: data.name, message: data.message});
});
});
server.listen(8080, function () {
console.log('listen me on: 8080');
});
and it works well when I'm trying to visit http://ip:8080/test so it means that node server is working, but when I try to create socket connection on my view file var socket = io.connect('http://ip:8080'); it gives me error:
The page at 'https://www.domain.com/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://ip:8080/socket.io/?EIO=3&transport=polling&t=1446818946199-0'. This request has been blocked; the content must be served over HTTPS.
so the problem is clear enough, but how to deal with it?
also I have tried this connection:
var socket = io.connect('https://www.domain.com:8080');
but the result is 404 GET Error. How to deal with it?
Update
now the part of code I should use, but don't know how to get cert of existing SSL in the server.
var socket = require('socket.io');
var express = require('express');
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('path/to/key.pem'), // dont have
cert: fs.readFileSync('path/to/cert.cert') // dont have
};
var app = express();
var server = https.createServer(options, app);
var io = socket.listen(server);
app.get('/test', function(req, res) {
res.send('hello world');
console.log('visited test')
});
io.sockets.on('connection', function (client) {
console.log("New client !");
client.on('message', function (data) {
console.log('Message received ' + data.name + ":" + data.message);
io.sockets.emit('message', {name: data.name, message: data.message});
});
});
server.listen(443, function () {
console.log('listen me on: 443');
});
I think you need to contact your certificate authority (the organization that issued your first ssl certificate) and get a copy of the certificate (the path/to/key.pem and path/to/cert.cert) or find the existing keys somewhere on your existing server.
If you're running apache, your configuration file will have a section with values for the paths of the .cert and .pem files labeled SSLCertificateFile and SSLCertificateKeyFile, then just update the paths in your node app to point to them. You also have to make sure that your SSL certificate meets the requirements (for example, needs to be Multi-domain if your node app runs on a different domain, or a Wildcard SSL certificate to run your node app on a subdomain).
The domain.com.csr and domain.com.key files you found are the private key and certificate request used to generate your initial SSL certificate and aren't going to do anything to enable SSL on your node app.

Get PHP $_SESSION from NodeJs

I'm trying to check the username in the NodeJs chat with the user session. Is there a secure way to do it? (My NodeJs server isn't in the same place as the host of the website). I'm using this code NodeJs + express to do the chat application.
Code:
var express = require('express');
var app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server, { log: false });
server.listen(8080);
app.get('/chat.js', function(req, res) {
res.sendfile('chat.js');
});
/* CHAT FUNCTIONS */
io.sockets.on('connection', function (socket) {
socket.on('send', function (data) {
// I wanna get the user session
// something like this:
// (code below does not exist)
var username = session['username'];
console.log(username + " is here.");
io.sockets.emit('message', data);
});
});
How can I do this?
You need to use common storage for sessions e.g. memcached or redis.
Than u will have common access.

Resources