HTTPS Redirect Setup
HTTPS redirect guarantees all site requests — including direct HTTP links, bookmarks, outdated links from other sites — redirect to HTTPS version. HSTS additionally protects against downgrade attacks.
Nginx: HTTP → HTTPS Redirect
# Redirect all HTTP traffic
server {
listen 80;
listen [::]:80;
server_name example.ru www.example.ru;
# Let's Encrypt .well-known — keep accessible via HTTP for renewal
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://example.ru$request_uri;
}
}
# Redirect www → non-www (or vice versa) + HTTPS
server {
listen 443 ssl;
server_name www.example.ru;
ssl_certificate /etc/letsencrypt/live/example.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.ru/privkey.pem;
return 301 https://example.ru$request_uri;
}
# Main server
server {
listen 443 ssl http2;
server_name example.ru;
# ...
}
HSTS (HTTP Strict Transport Security)
HSTS tells browser to always use HTTPS for this domain — even if user enters http://. Browser caches this for max-age seconds.
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
-
max-age=63072000— 2 years (recommended after testing) -
includeSubDomains— apply to all subdomains -
preload— add to browser preload list (hstspreload.org)
HSTS Implementation Order:
- Start with
max-age=300(5 minutes) — verify everything works - Increase to
max-age=86400(1 day) - Add
includeSubDomains— verify ALL subdomains on HTTPS - Increase to
max-age=31536000(1 year) - Add
preloadand register at hstspreload.org
HTTPS in Laravel Application
// AppServiceProvider
public function boot(): void
{
if (app()->environment('production')) {
URL::forceScheme('https');
// or
URL::forceRootUrl('https://example.ru');
}
}
// bootstrap/app.php — trustProxies for sites behind reverse proxy/CDN
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(
headers: Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO,
proxies: '*'
);
})
Without trustProxies — Laravel doesn't see request came via HTTPS (Nginx → PHP via HTTP), generates HTTP URLs in redirect headers and links.
Apache
# .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Cloudflare
In Cloudflare panel: SSL/TLS → Edge Certificates:
- Always Use HTTPS → enable
- HTTP Strict Transport Security (HSTS) → enable, max-age 12 months
Verification
# Check redirect
curl -I http://example.ru
# Should return: Location: https://example.ru/
# Check HSTS
curl -I https://example.ru | grep Strict
# Should return: Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
# Full redirect chain check
curl -IL http://www.example.ru
Timeline: 30 minutes for Nginx configuration and Laravel trustProxies.







