strictTransportSecurity function

Middleware strictTransportSecurity({
  1. StrictTransportSecurityOptions options = const StrictTransportSecurityOptions(),
})

This middleware adds the Strict-Transport-Security header to the response. This tells browsers, "hey, only use HTTPS for the next period of time". (See the spec for more.) Note that the header won't tell users on HTTP to switch to HTTPS, it will just tell HTTPS users to stick around. You can enforce HTTPS with the shelf-enforces-ssl package.

This will set the Strict Transport Security header, telling browsers to visit by HTTPS for the next 365 days:

import 'package:shelf_helmet/shelf_helmet.dart';

.addMiddleware(strictTransportSecurity())

// Sets "Strict-Transport-Security: max-age=15552000; includeSubDomains"

Note that the max age must be in seconds.

The includeSubDomains directive is present by default. If this header is set on example.com, supported browsers will also use HTTPS on my-subdomain.example.com.

You can disable this:

import 'package:shelf_helmet/shelf_helmet.dart';

.addMiddleware(strictTransportSecurity(includeSubDomains: false))

Some browsers let you submit your site's HSTS to be baked into the browser. You can add preload to the header with the following code. You can check your eligibility and submit your site at hstspreload.org.

import 'package:shelf_helmet/shelf_helmet.dart';

.addMiddleware(
    strictTransportSecurity(
        maxAge: const Duration(days: 365), // Must be at least 1 year to be approved
        preload: true
    ),
)

The header is ignored in insecure HTTP, so it's safe to set in development.

This header is somewhat well-supported by browsers.

Implementation

Middleware strictTransportSecurity({
  StrictTransportSecurityOptions options =
      const StrictTransportSecurityOptions(),
}) {
  final List<String> args = [
    'max-age=${options.maxAge.inSeconds}',
    if (options.includeSubDomains) 'includeSubDomains',
    if (options.preload) 'preload',
  ];
  return (innerHandler) {
    return (request) async {
      final response = await innerHandler(request);
      return response.change(
        headers: {
          'strict-transport-security': args.join('; '),
          ...response.headersAll,
        },
      );
    };
  };
}