verifyJwtHS256Signature function
JwtExpress
verifyJwtHS256Signature(
- String token,
- String hmacKey, {
- JOSEHeaderCheck? headerCheck = defaultJWTHeaderCheck,
- bool defaultIatExp = true,
- Duration maxAge = JwtExpress.defaultMaxAge,
Verifies the signature and extracts the claim set from a JWT.
The signature is verified using the hmacKey
with the HMAC SHA-256
algorithm.
The headerCheck
is an optional function to check the header.
It defaults to defaultJWTHeaderCheck.
Normally, if either the Issued At Claim and/or Expiration Time Claim
are not present, default values are assigned to them.
This behaviour can be disabled by setting defaultIatExp
to false.
See the constructor JwtExpress for details about what default values are
used and how maxAge
is used.
Throws a JwtExpressException if the signature does not verify or the JWT is invalid.
final decClaimSet = verifyJwtHS256Signature(token, key);
print(decClaimSet);
Implementation
JwtExpress verifyJwtHS256Signature(String token, String hmacKey,
{JOSEHeaderCheck? headerCheck = defaultJWTHeaderCheck,
bool defaultIatExp = true,
Duration maxAge = JwtExpress.defaultMaxAge}) {
try {
final hmac = Hmac(sha256, hmacKey.codeUnits);
final parts = token.split('.');
if (parts.length != 3) {
throw JwtExpressException.invalidToken;
}
// Decode header and payload
final headerString = B64urlEncRfc7515.decodeUtf8(parts[0]);
// Check header
final dynamic header = json.decode(headerString);
if (header is Map) {
// Perform any custom checks on the header
if (headerCheck != null &&
!headerCheck(header.cast<String, dynamic?>())) {
throw JwtExpressException.invalidToken;
}
if (header['alg'] != 'HS256') {
throw JwtExpressException.hashMismatch;
}
} else {
throw JwtExpressException.headerNotJson;
}
// Verify signature: calculate signature and compare to token's signature
final data = '${parts[0]}.${parts[1]}';
final calcSig = hmac.convert(data.codeUnits).bytes;
final tokenSig = B64urlEncRfc7515.decode(parts[2]);
// Signature does not match calculated
if (!secureCompareIntList(calcSig, tokenSig))
throw JwtExpressException.hashMismatch;
// Convert payload into a claim set
final payloadString = B64urlEncRfc7515.decodeUtf8(parts[1]);
final dynamic payload = json.decode(payloadString);
if (payload is Map) {
return JwtExpress.fromMap(payload.cast(),
defaultIatExp: defaultIatExp, maxAge: maxAge);
} else {
throw JwtExpressException
.payloadNotJson; // is JSON, but not a JSON object
}
} on FormatException {
// Can be caused by:
// - header or payload parts are not Base64url Encoding
// - bytes in the header or payload are not proper UTF-8
// - string in header or payload cannot be parsed into JSON
throw JwtExpressException.invalidToken;
}
}