lcobucci/jwt は、解析、署名、検証を分離しています。Configuration が署名器と鍵を保持し、parser()->parse() は何もチェックせずにトークンを読み取り、validator()->assert() は渡された制約を適用します。制約なしで assert() を呼び出すと NoConstraintsGiven がスローされるため、何もチェックしない検証をうっかり書いてしまうことは起こりにくくなっています。
SignedWith は署名器と鍵を固定します。RS256 トークンも、EC 鍵の PEM テキストで偽造した HS256 トークンも、Token signer mismatch で失敗しました。署名のないトークンは解析すらできません(The JWT string is missing the Signature part)。鍵長は署名時に強制されます。ES256 は P-384 の鍵を拒否し(The length of the provided key is different than 256 bits)、HS256 は 40 ビットの鍵を拒否しました。そのため、不正な形式のトークンがそもそも生成されません。
時刻のチェックも制約なので、列挙したときにしか実行されません。1 時間前に期限切れになったトークンも、SignedWith だけなら通りました。LooseValidAt は exp、nbf、iat があればチェックし、exp のないトークンを受け入れました。StrictValidAt は 3 つすべてを必須とし、iat のないトークンは "Issued At" claim missing で、iat と exp はあっても nbf のないトークンは "Not Before" claim missing で失敗しました。どちらも時刻のずれを許容する間隔(leeway)を任意で受け取り、デフォルトはゼロです。サンプルでは 3 つのクレームをすべて設定し、1 回の呼び出しで署名、発行者、厳格な有効性をまとめて検証します。
バージョン 5.6.1 は 256/384/512 の HS、RS、ES と EdDSA に対応しています。PS* の署名器と ES256K はないため、RSA-PSS を使う発行者のトークンには web-token が必要です。ES256 署名は 64 バイトの生の r‖s で、DER の署名は Token signature mismatch で失敗します。トークンがどちらのエンコーディングかは JWT デバッガーで確認できます。