HTTPS Setup for Local Development
Many modern browser features require HTTPS, including:
- Service Workers
- Progressive Web Apps (PWA)
- Web Authentication (WebAuthn/Passkeys)
- Secure Cookies (
SameSite=None; Secure) - Camera and Microphone APIs
- Geolocation APIs
- Some OAuth and SSO authentication flows
While localhost is treated as a secure context for some browser features, testing with real HTTPS certificates is often necessary.
Multiple Options Available
Option 1: Use OpenSSL to Create a Self-Signed Certificate
Generate Certificate
openssl req -x509 -newkey rsa:4096 \
-keyout key.pem \
-out cert.pem \
-days 365 \
-nodes
This generates:
cert.pem
key.pem
Run http-server with HTTPS
http-server -S -C cert.pem -K key.pem
Browse to:
https://localhost:8080
Expected Browser Warning
You will typically see a warning such as:
Your connection is not private
This is normal because the certificate is self-signed.
Option 2: Use mkcert (Recommended)
mkcert creates locally trusted development certificates and avoids browser security warnings.
Install mkcert
Windows
winget install FiloSottile.mkcert
macOS
brew install mkcert
Linux
See project documentation for distribution-specific packages.
Install Local Certificate Authority
mkcert -install
Generate Certificates
mkcert localhost
Generated files:
localhost.pem
localhost-key.pem
Use with http-server
http-server \
-S \
-C localhost.pem \
-K localhost-key.pem
Browse to:
https://localhost:8080
Benefits:
- Trusted by the local machine
- No browser warnings
- Works with Chrome, Edge, Firefox, and Safari
- Excellent for testing authentication flows
Option 3: HTTPS with Python
Python's built-in server does not natively support HTTPS from a simple command line option.
Create a file named https_server.py:
from http.server import HTTPServer, SimpleHTTPRequestHandler
import ssl
httpd = HTTPServer(('localhost', 4443), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(
httpd.socket,
certfile='cert.pem',
keyfile='key.pem',
server_side=True
)
httpd.serve_forever()
Run:
python https_server.py
Browse to:
https://localhost:4443
Option 4: HTTPS with Node.js Express
Install Express:
npm install express
Example HTTPS server:
const https = require('https');
const fs = require('fs');
const express = require('express');
const app = express();
app.use(express.static('.'));
https.createServer({
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
}, app).listen(8443);
Run:
node server.js
Browse to:
https://localhost:8443
Option 5: HTTPS with NGINX in Docker
Mount certificates into the container and configure SSL:
docker run -d \
-p 443:443 \
-v $(pwd)/certs:/etc/nginx/certs \
-v $(pwd)/html:/usr/share/nginx/html \
nginx
This approach closely mirrors production environments.
Common HTTPS Testing Scenarios
Testing Secure Cookies
Example:
Set-Cookie: token=abc123; Secure; SameSite=None
Without HTTPS, browsers often reject these cookies.
Testing OAuth Authentication
Many identity providers require:
https://localhost
instead of:
http://localhost
for redirect URIs.
Examples include:
- Azure AD / Microsoft Entra ID
- Okta
- Auth0
- Keycloak
- Google Identity Services
Testing Service Workers
Service workers require a secure context:
navigator.serviceWorker.register('/sw.js');
This works only on:
https://
or
localhost
origins.
HTTPS Troubleshooting
ERR_CERT_AUTHORITY_INVALID
Cause:
Certificate is not trusted.
Fix:
- Use
mkcert - Import the certificate into the local trust store
ERR_CERT_COMMON_NAME_INVALID
Cause:
The hostname does not match the certificate.
Example:
Certificate issued for localhost
Accessing 127.0.0.1
Fix:
Generate the certificate with all required hostnames:
mkcert localhost 127.0.0.1
Port 443 Requires Elevated Privileges
Linux/macOS may require administrator privileges:
sudo http-server -S -p 443
Alternative:
Use a higher port:
https://localhost:8443
Recommended HTTPS Approach
For most developers:
- Install
mkcert - Create a trusted local certificate
- Use
http-serveror your framework's HTTPS support - Test using:
https://localhost
This provides the closest experience to a production HTTPS deployment while remaining simple to maintain.