validate static method

Future<JsonWebToken> validate(
  1. String token, {
  2. required String key,
})

Implementation

static Future<JsonWebToken> validate(
  String token, {
  required String key,
}) async {
  final parts = token.split('.');

  if (parts.length != 3) {
    throw ServiceException(
      body: '[JwtUtils]: Invalid token; [3] != [${parts.length}]',
      code: 401,
    );
  }

  final header =
      json.decode(utf8.decode(_decodeBase64EncodedBytes(parts[0])));
  final jwt = JsonWebToken.unverified(token);

  if ((jwt.claims.expiry?.millisecondsSinceEpoch ?? 0) <
      DateTime.now().millisecondsSinceEpoch) {
    throw ServiceException(
      code: 403,
      body: 'Token is expired',
    );
  }

  JsonWebKey jwk;
  final alg = header['alg'];
  final keyId = header['kid'];

  switch (alg) {
    case 'HS256':
      jwk = JsonWebKey.fromJson({
        if (keyId != null) 'kid': keyId,
        'kty': 'oct',
        'k': key,
      });
      break;

    case 'RS256':
      final pk = parsePem(key).first;
      jwk = JsonWebKey.rsa(
        exponent: pk.exponent,
        keyId: keyId,
        modulus: pk.modulus,
      );
      break;

    default:
      throw ServiceException(
        body: '[JwtUtils]: unsupported algorithm [${alg}]',
        code: 401,
      );
  }

  final keyStore = JsonWebKeyStore()..addKey(jwk);
  final verified = await jwt.verify(keyStore);

  if (verified != true) {
    throw ServiceException(
      body: '[JwtUtils]: Invalid JWT Signature',
      code: 401,
    );
  }

  return jwt;
}