Skip to content

Commit

Permalink
Merge pull request #6 from alex-ng-wesoft/bugfix/issue5-fix-jwt-encod…
Browse files Browse the repository at this point in the history
…e-base64

Use Base64url to encode headers and payload in `JWT::encode()`
  • Loading branch information
ADmad committed Aug 16, 2023
2 parents a1dbb02 + ed806a3 commit 5eaf255
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/JWT.php
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,8 @@ public function encode(string $privateKeyOrSecret, string $alg, EncodeOptions $o
throw new InvalidJWT('Cannot encode payload to JSON');
}

$header64 = base64_encode($headerStr);
$payload64 = base64_encode($payloadStr);
$header64 = JWT::urlsafeB64Encode($headerStr);
$payload64 = JWT::urlsafeB64Encode($payloadStr);

$signature = $this->signature($privateKeyOrSecret, $alg, "{$header64}.{$payload64}");
$signature64 = JWT::urlsafeB64Encode($signature);
Expand Down
49 changes: 49 additions & 0 deletions tests/JWTTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -379,4 +379,53 @@ public function testEncodeToDecodeSuccess(
$headers = $jwt->getHeaders();
parent::assertArrayHasKey('alg', $headers);
}

public function testEncodeUsesBase64UrlEncoding()
{
$privateKey = file_get_contents(__DIR__ . '/assets/rs256.key');
assert(is_string($privateKey));

$payload = ['foo' => 'bar'];
$payloadJsonStr = \json_encode($payload);
assert(is_string($payloadJsonStr));
$payloadStandardBase64 = \base64_encode($payloadJsonStr);
parent::assertStringContainsString(
'=',
$payloadStandardBase64,
'Test pre-requisite failed: Standard Base64 encoded payload string has no padding'
);

$headers = [
'alg' => 'RS256',
'a' => 'b',
'typ' => 'JWT'
];
$headersJsonStr = \json_encode($headers);
assert(is_string($headersJsonStr));
$headersStandardBase64 = \base64_encode($headersJsonStr);
parent::assertStringContainsString(
'=',
$headersStandardBase64,
'Test pre-requisite failed: Standard Base64 encoded headers string has no padding'
);

$token = new JWT($payload, $headers);
$jwtAsString = $token->encode($privateKey, 'RS256', new EncodeOptions());

parent::assertStringNotContainsString(
'=',
$jwtAsString,
'Encoded JWT contains padding, which is not valid Base64url'
);
parent::assertStringNotContainsString(
'+',
$jwtAsString,
'Encoded JWT contains + character, which is not valid Base64url'
);
parent::assertStringNotContainsString(
'/',
$jwtAsString,
'Encoded JWT contains / character, which is not valid Base64url'
);
}
}

0 comments on commit 5eaf255

Please sign in to comment.