Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Base64url to encode headers and payload in JWT::encode() #6

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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'
);
}
}
Loading