In the latest release of Google Chrome, Google has enforced a rule that they had previously stated they would which requires that any page requesting camera or microphone access through "getUserMedia" be delivered from localhost or a server serving pages with HTTPS. [1], [2]
HTTPS is a "secure" version of HTTP. It uses SSL or TLS to encrypt the contents of HTTP. Traditionally it has been used for banking and other more sensitive content, now it's use is widespread.
Normally to serve pages with HTTPS you need to get certificate that verifies your identity from a Certificate Authority.
More about Public Key Cryptography: Public Key Cryptography: Diffie-Hellman Key Exchange
Unfortunately, a real certificate form a CA requires time, money, and a domain for your site. Being that these are 3 things that we don't have at the moment.. let's use a "self-signed certificate". Here are the steps:
Create a private key:
openssl genrsa -out my-key.pem 2048This command generates a 2048 bit key (saved as my-key.pem) that can be used to encrypt data (such as web pages)
Create a Certificate Signing Request:
openssl req -new -sha256 -key my-key.pem -out my-csr.pemThis command generates a file which is normally sent to a Certificate Authority to have them verify your identity and issue you an SSL certificate. We are going to be confirming our own identity to the information here doesn't have to be as accurate as it would otherwise have to be.
Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:New York Locality Name (eg, city) []:Brooklyn Organization Name (eg, company) [Internet Widgits Pty Ltd]:Live Web Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:Live Web Email Address []:Shawn.Van.Every@nyu.edu Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:The CSR will be saved as my-csr.pem.
Finally we "self-sign" by running this command:
openssl x509 -req -in my-csr.pem -signkey my-key.pem -out my-cert.pemThis generates a certificate file called my-cert.pem that we can use in combination with the private key to enable SSL/HTTPS on our Node.js servers.
Fortunately, node has a drop in replacement for the "http" library called "https". Here is a basic https webserver example:
var https = require('https'); var fs = require('fs'); // Using the filesystem module var url = require('url'); var options = { key: fs.readFileSync('my-key.pem'), cert: fs.readFileSync('my-cert.pem') }; function handleIt(req, res) { var parsedUrl = url.parse(req.url); var path = parsedUrl.pathname; if (path == "/") { path = "index.html"; } fs.readFile(__dirname + path, // Callback function for reading function (err, fileContents) { // if there is an error if (err) { res.writeHead(500); return res.end('Error loading ' + req.url); } // Otherwise, send the data, the contents of the file res.writeHead(200); res.end(fileContents); } ); // Send a log message to the console console.log("Got a request " + req.url); } var httpServer = https.createServer(options, handleIt); httpServer.listen(8080);If you use this in place of a regular http version of our servers, and the user allows the self-signed certificate, the getUserMedia requests will work once again.