validate method

void validate({
  1. String? issuer,
  2. String? audience,
  3. Duration? allowedClockSkew,
  4. DateTime? currentTime,
})

Validates the JWT claim set.

Checks the for the issuer and audience and validates the Expiration Time Claim and Not Before claim, if they are present.

The time claims in the token (i.e. Expiry, Not Before and Issued At) are checked with the current time. A value for currentTime can be provided (this is useful for validating tokens previously received/saved/created), otherwise the current time of when this method is invoked is used.

To ensure the claim set is sensible, validation will fail if the Expiration Time Claim is before the Not Before Claim, or the Expiration Time Claim is before the Issued At Claim.

An allowedClockSkew can be provided to allow for differences between the clock of the system that created the token and the clock of the system doing the validation. By default, there is no allowance for clock skew (i.e. it defaults to a duration of zero).

Implementation

void validate(
    {String? issuer,
    String? audience,
    Duration? allowedClockSkew,
    DateTime? currentTime}) {
  // Ensure clock skew has a value and is never negative
  final absClockSkew = allowedClockSkew?.abs() ?? const Duration();

  // Check Issuer Claim
  if (issuer != null) {
    if (issuer != this.issuer) {
      throw JwtException.incorrectIssuer;
    }
  }

  // No checks for subject: the application is supposed to do that

  // Check Audience Claim
  if (audience != null) {
    if (this.audience != null && !this.audience!.contains(audience)) {
      throw JwtException.audienceNotAllowed;
    }
  }

  // Validate time claims (if present) are consistent
  // i.e. Expiry is not before NotBefore, and expiry is not before IssuedAt
  if (expiry != null && notBefore != null && !expiry!.isAfter(notBefore!)) {
    throw JwtException.invalidToken;
  }
  if (expiry != null && issuedAt != null && !expiry!.isAfter(issuedAt!)) {
    throw JwtException.invalidToken;
  }

  // Validate time claims against the current time
  //
  // This implementation only checks a time claim if it is present in the
  // token (they are all optional according to RFC 7519).
  // Note: the current constructor always ensures the issuedAt and Expires
  // time claims are always populated (even when it is created from an encoded
  // token that didn't have them).
  final cTime = (currentTime ?? DateTime.now()).toUtc();

  // Check Expiration Time Claim
  // Reject the token if the current time is at or after the Expiry time.
  // (At exactly Expiry is also rejected.)
  if (expiry != null && !cTime.isBefore(expiry!.add(absClockSkew))) {
    throw JwtException.tokenExpired;
  }

  // Check Not Before Claim
  // Reject token if the current time is before the Not Before time.
  // (At exactly Not Before is ok.)
  if (notBefore != null && notBefore!.subtract(absClockSkew).isAfter(cTime)) {
    throw JwtException.tokenNotYetAccepted;
  }

  // No checks for Issued At Claim
  //
  // RFC7519 only says this "can be used to determine the age of the JWT".
  //
  // Some issuers deliberately set a NotBefore time to be one minute before
  // the Issued At time. So they seem to expect NotBefore to be checked, but
  // not IssuedAt.

  // No checks for JWT ID Claim: the application is supposed to do that
}