Setting Up Local Development Server with Self-signed SSL Certificate for DeviceOrientation/DeviceMotion API
Since iOS 13, Apple has made it so that if a web page requires access to the DeviceOrientation or DeviceMotion API in the browser, the site will need to request permission for it. In addition to that, the site must also be served over HTTPS, including localhost
.
However, even if localhost
is exempted, for a typical use case for local development of a website that uses the above mentioned API, which is running a local server on a computer connected to a network then accessing a web page served from the server from one’s mobile device connected to the same network, it won’t work (and it probably shouldn’t).
I’m documenting here the few setups that I have for overcoming this issue. It is by no means the best or the most ideal but hopefully it is useful. I’m also only focusing on Node.js based solution and a frontend project. For a full stack project I will write a follow up instead.
Before we go any further, here’s an important security note:
Some parts of this instructions may ask you to manually bypass browser security warning. Please note you should only do it in the cases listed below and no more than that. NEVER manually bypass browser security warnings on pages whose certificate you don’t know!
Project Setup
I’m going to use p5.js here so I don’t have to go too much into the DeviceOrientation and DeviceMotion API here. In p5.js rotationX/Y/Z
and accelerationX/Y/Z
are a thin wrapper around the values returned by the native APIs so if you are using the native API, it should work similarly.
The p5.js sketch is as simple as the above while index.html
is minimal, you can use the one that comes with the empty example from p5.js complete download.
First we need to serve the file from a server, we can use http-server to spin up a simple web server quickly and view the page from http://localhost:8080
by default. Here’s what it looks like:
If you want to preview this on your mobile device, you will need to find your local network IP address or hostname. We’ll assume you have the local IP address for your computer, if you cannot find it, you can do a quick search online for how to find it (keyword is “local IP”). With the IP address, as long as your smartphone is connected to the same network (eg. same Wi-Fi), you can key in the IP address and port in the mobile browser and it should show up.
But as you can see, the rotation values are still 0 even on the mobile device. In this particular case (iOS) there are two reasons for it.
- Since iOS 13, websites are now required to explicitly request permission from the user in order to access the API. This request must be called as a result of user interaction, typically a click event.
- The website must be served through a secure connection (ie. a HTTPS connection).
These two problems must both be solved or the API will not return a value. To get around problem 1, we modify our code by adding a click event on the canvas itself and calling the requestPermission
function.
For problem 2, we will need to somehow establish a HTTPS connection to the server running on our computer. While http-server
supports accepting SSL certificates with the -S
-K
-C
arguments, they still require manually generating self-signed certificate. Whereas Parcel’s development server automatically generates a self-signed certificate. The nature of Parcel’s bundling process makes using our sketch code above difficult as the global setup()
and draw()
functions will get scoped after bundling thus breaking p5.js’ global mode functionality. If you are not using p5.js in global mode, Parcel gets a full recommendation here.
For our case however, I’ve forked http-server and added the ability to generate self-signed certificate using the same code as used in Parcel. (This isn’t fully released yet and will not be named http-server
if and when it does release) You can install it as a CLI tool with :
npm install -g https://github.com/limzykenneth/http-server.git
You may need to uninstall existing version of http-server
if exist before running the above step. Once installed, you can run http-server -S
and it will generate a certificate pair in the ssl-certificate
folder and start the server using this certificate.
Navigate to https://localhost:8080/
to view the project. Your browser will display a big warning saying the site is potentially dangerous or insecure, they are absolutely right! If you skip the warning before, go back and read them now!
Gingerly, we will manually bypass the warning as we know this self-signed certificate is valid since we just generated it for development purposes, in Firefox, click on “Advanced” and “Accept the Risk and Continue”. Your sketch should display as before now on your browser.
For mobile, just go to the same IP address as before but instead of http
make sure it is https
now. Bypass the browser warning here as well. Tap on the canvas and you should be prompted for permission to allow access to the API, tap on “Allow”, hopefully now you will see sensor values displayed in the sketch!
If that’s all you need, you can stop here.
If you need a full stack solution, you can look at part two of this tutorial.