authenticate method

RequestHandler authenticate(
  1. dynamic type, [
  2. AngelAuthOptions<User>? opt
])

Attempts to authenticate a user using one or more strategies.

type is a strategy name to try, or a List of such.

If a strategy returns null or false, either the next one is tried, or a 401 Not Authenticated is thrown, if it is the last one.

Any other result is considered an authenticated user, and terminates the loop.

Implementation

RequestHandler authenticate(type, [AngelAuthOptions<User>? opt]) {
  return (RequestContext req, ResponseContext res) async {
    var authOption = opt ?? AngelAuthOptions<User>();

    var names = <String>[];

    var arr = type is Iterable
        ? type.map((x) => x.toString()).toList()
        : [type.toString()];

    for (var t in arr) {
      var n = t
          .split(',')
          .map((s) => s.trim())
          .where((String s) => s.isNotEmpty)
          .toList();
      names.addAll(n);
    }

    for (var i = 0; i < names.length; i++) {
      var name = names[i];

      var strategy = strategies[name];
      if (strategy == null) {
        _log.severe('No strategy "$name" found.');
        throw ArgumentError('No strategy "$name" found.');
      }

      var reqContainer = req.container;

      if (reqContainer == null) {
        print('req.container is null');
      }

      var hasExisting = reqContainer?.has<User>() ?? false;
      var result = hasExisting
          ? reqContainer?.make<User>()
          : await strategy.authenticate(req, res, authOption);

      if (result == true) {
        return result;
      } else if (result != null && result != false) {
        //} else if (result != null && result is Map && result.isNotEmpty) {
        var userId = await serializer(result);

        // Create JWT
        var token = AuthToken(
            userId: userId, lifeSpan: _jwtLifeSpan, ipAddress: req.ip);
        var jwt = token.serialize(_hs256);

        if (authOption.tokenCallback != null) {
          var hasUser = reqContainer?.has<User>() ?? false;
          if (!hasUser) {
            reqContainer?.registerSingleton<User>(result);
          }

          var r = await authOption.tokenCallback!(req, res, token, result);
          if (r != null) return r;
          jwt = token.serialize(_hs256);
        }

        _apply(req, res, token, result);

        if (allowCookie) {
          _addProtectedCookie(res, 'token', jwt);
        }

        // Options is not null
        if (authOption.callback != null) {
          return await authOption.callback!(req, res, jwt);
        }

        if (authOption.successRedirect?.isNotEmpty == true) {
          await res.redirect(authOption.successRedirect);
          return false;
        } else if (authOption.canRespondWithJson &&
            req.accepts('application/json')) {
          var user = hasExisting
              ? result
              : await deserializer(await serializer(result));
          _onLogin.add(user);
          return {'data': user, 'token': jwt};
        }

        return true;
      } else {
        if (i < names.length - 1) continue;
        // Check if not redirect
        if (res.statusCode == 301 ||
            res.statusCode == 302 ||
            res.headers.containsKey('location')) {
          return false;
        } else if (authOption.failureRedirect != null) {
          await res.redirect(authOption.failureRedirect);
          return false;
        } else {
          _log.warning('Not authenticated');
          throw AngelHttpException.notAuthenticated();
        }
      }
    }
  };
}