• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer
webrtcHacks

webrtcHacks

Guides and information for WebRTC developers

  • Home
  • About
    • Chad Hart
    • Philipp Hancke
  • Subscribe
  • Contact
  • Show Search
Hide Search

Guide Chrome, code, getUserMedia, HTTPS, Walkthrough, xander dumaine Xander Dumaine · December 17, 2015

Surviving Mandatory HTTPS in Chrome (Xander Dumaine)

“Only Secure Origins Are Allowed”

        – Chrome 47

Chrome 47 now forces secure origins (mostly) with HTTPS. This can be a pain to deal with, but Xander Dumaine is here to help with some guidance. Xander is a Senior Software Engineer who deals with the good and bad of WebRTC for Interactive Intelligence in Raleigh, NC. He is helping maintain simpleWebRTC and organises the Triangle WebRTC Meetup group in that area.

{“editor”: “chad hart“}

No thoroughfare

Chrome 47 brought a new change, and one that’s caused a lot of confusion and irritation for some WebRTC developers. Despite the warnings and PSAs from the WebRTC team at Google, and the console deprecation warning, some didn’t get the message that getUserMedia now requires that the requesting app be served over HTTPS.

Here are a couple tips for quickly getting up and running with getUserMedia on HTTPS in development and when deployed.

Development

localhost exception

The only exception to the HTTPS requirement is localhost. If you’re developing from a local server, you should be fine, as you can serve on localhost with HTTP or HTTPs.

So what happens if you’re developing from a different IP or host? If you’re comfortable setting up self signed certs for your services, you’re good to go. For many, this might be prohibitive.

getUserMedia Warning

scenario diagram

Local proxy to localhost

Often developers will have a container or collection of containers for serving an application and related services. These typically all use HTTP communication. If you were to simply start serving the web content over HTTPS, and you’re connecting to a WebSocket for signaling, you’ll find that Chrome disallows connecting to an insecure WebSocket from a secure origin. In this case, you’ll want to continue using all HTTP traffic, but the only way to do so is with localhost.  To do this, you really just want to create a reverse proxy for the web content. You can pick your own favorite method of doing this, but one that I find very easy is a little nginx proxy:

nginx.conf proxy
1
2
3
4
5
6
7
server {
    listen 8080;
    server_name localhost;
    location / {
        proxy_pass         http://your.dev.box.ip:8080;
    }
}

Now, you can just visit http://localhost:8080. Your page will be served over HTTP, but because it’s localhost, Chrome allows getUserMedia to continue, and you don’t have to worry about upgrading your WebSockets (WS) to secure WebSockets (WSS).

Proxy Diagram

HTTPS proxy

Alternatively, if you do want to serve your web content over HTTPS, but don’t want to modify your services to use secure WebSockets for development, you can use a simple proxy to to upgrade your WebSockets as well. I have an example of those in node, using express:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var express = require('express');
var https = require('https');
var httpProxy = require('http-proxy');
var pem = require('pem');
 
pem.createCertificate({ days: 1, selfSigned: true }, function (err, keys) {
    var httpsOptions = {
        key: keys.serviceKey,
        cert: keys.certificate
    };
    
    var proxy = httpProxy.createProxyServer({
        target: http://signaling.example.com,
        ws: true,
        secure: false,
        changeOrigin: true
    });
 
    var proxyWebsocket = function (req, socket, head) {
        // replace the target with your signaling server ws url
        proxy.ws(req, socket, head, {
            target: 'http://signaling.example.com'
        });
    };
 
    var app = express();
    var server = https.createServer(httpsOptions, app);
    server.on('upgrade', proxyWebsocket);
 
    server.listen(8443);
});

With this method, you can create a secure websocket request to https://localhost:8443, which will be proxied to an insecure websocket to your development signaling server.

Deployment

When deploying your app, there are lots of ways to get HTTPS, like paying your hosting provider, or buying a cert yourself, but there are also some easy, free alternatives.

I’ve used two primary options for quick apps – Github Pages or surge + free CloudFlare https. Both are great if your apps is a static client app, and both allow you to use your own domain, with free SSL. Note that if this is a WebRTC app (not just getUserMedia) and you’ve got a WebSocket for signaling, you’ll still have to make sure your signaling server has HTTPS as well. And for the near future, more free SSL is right around the corner.

Happy Encrypting!

{“author”, “Xander Dumaine“}

Guide Chrome, code, getUserMedia, HTTPS, Walkthrough, xander dumaine

Related Posts

  • getUserMedia Mirrors and Frame RatesgetUserMedia Mirrors and Frame Rates
  • How to use WebRTC and Chrome Extensions to Call a Browser When it is Not Open (Konstantin Goncharuk)How to use WebRTC and Chrome Extensions to Call a Browser When it is Not Open (Konstantin Goncharuk)
  • How to Figure Out WebRTC Camera ResolutionsHow to Figure Out WebRTC Camera Resolutions
  • getUserMedia – What happens when there’s missing media sources?getUserMedia – What happens when there’s missing media sources?

RSS Feed

Reader Interactions

Comments

  1. Chad McElligott says

    December 18, 2015 at 7:31 am

    ngrok.com is another nice resource for getting an HTTPS link to your development app. Very easy to use. I use it all the time and have had very few issues with it.

    Reply
    • Coolio Jones says

      September 29, 2017 at 2:19 pm

      I don’t believe this resolves the issue. You can use the https link provided by ngrok but Chrome will still not permit getUserMedia

      Reply
  2. gman says

    February 21, 2016 at 9:34 pm

    If you’re using containers another solution is just to stick an HTTPS proxy in front. Just added a few lines to my docker-compose file and was done

    https://github.com/dmp1ce/nginx-proxy-letsencrypt

    Reply
  3. Aaron Gokaslan says

    May 28, 2016 at 1:25 pm

    I also found an extremely easy way to solve this issue for testing, no advanced setup required. There is a Python library that will forward all requests to a certain port(s) on localhost to any websites you choose. This allows for easy and rapid debugging since it takes advantage of the localhost exception for the policy.

    https://pypi.python.org/pypi/maproxy

    Note: This library is not in the Python base package, but it can easily be installed with pip.

    Reply
    • Chad Hart says

      May 28, 2016 at 1:30 pm

      Thank you for sharing!

      Reply
  4. darkknigh27 says

    January 23, 2017 at 5:39 am

    Hey, I am using getUserMedia in an iframe(https source) in a page deployed over http. How can i make this work? I am getting the same warning in the console

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

  • Sponsored. Become a webtcHacks sponsor

Email Subscription

Subscribe to our mailing list

* indicates required

Twittering

Tweets by @webRTChacks
webrtcHacksguides and information for WebRTC developers

Footer

SITE

  • Post List
  • About
  • Contact

Categories

  • Guide
  • Other
  • Reverse-Engineering
  • Standards
  • Technology

Tags

apple Blackbox Exploration Brief camera Chrome code computer vision DataChannel debug e2ee Edge extension gateway getUserMedia ICE ims insertable streams ios ip leakage janus jitsi MCU Microsoft NAT opensource Opus ORTC Promo Q&A raspberry pi Safari SDES SDP sfu signaling simulcast standards TURN video vp8 w3c Walkthrough Web Audio webrtc-internals wireshark

Follow

  • Twitter
  • YouTube
  • GitHub
  • RSS

webrtcHacks · copyright © 2023