diff --git a/src/JWT.php b/src/JWT.php index 6efcbb56..26349206 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -203,13 +203,14 @@ public static function encode( string $keyId = null, array $head = null ): string { - $header = ['typ' => 'JWT', 'alg' => $alg]; + $header = ['typ' => 'JWT']; + if (isset($head) && \is_array($head)) { + $header = \array_merge($header, $head); + } + $header['alg'] = $alg; if ($keyId !== null) { $header['kid'] = $keyId; } - if (isset($head) && \is_array($head)) { - $header = \array_merge($head, $header); - } $segments = []; $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($header)); $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($payload)); diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 13240410..b59c3c20 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -518,4 +518,26 @@ public function testGetHeaders() $this->assertEquals($headers->typ, 'JWT'); $this->assertEquals($headers->alg, 'HS256'); } + + public function testAdditionalHeaderOverrides() + { + $msg = JWT::encode( + ['message' => 'abc'], + 'my_key', + 'HS256', + 'my_key_id', + [ + 'cty' => 'test-eit;v=1', + 'typ' => 'JOSE', // override type header + 'kid' => 'not_my_key_id', // should not override $key param + 'alg' => 'BAD', // should not override $alg param + ] + ); + $headers = new stdClass(); + JWT::decode($msg, new Key('my_key', 'HS256'), $headers); + $this->assertEquals('test-eit;v=1', $headers->cty, 'additional field works'); + $this->assertEquals('JOSE', $headers->typ, 'typ override works'); + $this->assertEquals('my_key_id', $headers->kid, 'key param not overridden'); + $this->assertEquals('HS256', $headers->alg, 'alg param not overridden'); + } }