basicAuthentication<T extends Object> function

Middleware basicAuthentication<T extends Object>({
  1. @Deprecated('Deprecated in favor of authenticator. ' 'This will be removed in future versions') Future<T?> userFromCredentials(
    1. String username,
    2. String password
    )?,
  2. Future<T?> authenticator(
    1. RequestContext context,
    2. String username,
    3. String password
    )?,
  3. Applies applies = _defaultApplies,
})

Authentication that uses the Authorization header with the Basic scheme.

Basic scheme expects the header to be in the format:

Authorization: Basic <token>

Token should be a base64 encoded string of the format:

<username>:<password>

In order to use this middleware, you must provide a function that will return a user object from the username, password and request context.

If the given function returns null for the given username and password, the middleware will return a 401 Unauthorized response.

By default, this middleware will apply to all routes. You can change this behavior by providing a function that returns a boolean value based on the RequestContext. If the function returns false, the middleware will not apply to the route and the call will have authentication validation.

Implementation

Middleware basicAuthentication<T extends Object>({
  @Deprecated(
    'Deprecated in favor of authenticator. '
    'This will be removed in future versions',
  )
  Future<T?> Function(
    String username,
    String password,
  )? userFromCredentials,
  Future<T?> Function(
    RequestContext context,
    String username,
    String password,
  )? authenticator,
  Applies applies = _defaultApplies,
}) {
  assert(
    userFromCredentials != null || authenticator != null,
    'You must provide either a userFromCredentials or a '
    'authenticator function',
  );
  return (handler) => (context) async {
        if (!await applies(context)) {
          return handler(context);
        }

        Future<T?> call(String username, String password) async {
          if (userFromCredentials != null) {
            return userFromCredentials(username, password);
          } else {
            return authenticator!(context, username, password);
          }
        }

        final authorization = context.request.headers.basic();
        if (authorization != null) {
          final [username, password] =
              String.fromCharCodes(base64Decode(authorization)).split(':');

          final user = await call(username, password);
          if (user != null) {
            return handler(context.provide(() => user));
          }
        }

        return Response(statusCode: HttpStatus.unauthorized);
      };
}