Skip to content

Commit 9515146

Browse files
committed
Implement state parameter (take two)
The previous implementation incorrectly took state from the token claims, but it is returned as a normal query parameter to the callback, so outside the scope of client libraries.
1 parent 372b895 commit 9515146

File tree

2 files changed

+34
-30
lines changed

2 files changed

+34
-30
lines changed

client-tester.php

+26-26
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
<?php
33

44
$argv = $_SERVER['argv'];
5-
if (count($argv) !== 2) {
5+
if (2 !== count($argv)) {
66
error_log('Broker required');
77
exit(1);
88
}
99

10-
require_once __DIR__ . '/vendor/autoload.php';
10+
require_once __DIR__.'/vendor/autoload.php';
1111

1212
$client = new \Portier\Client\Client(
1313
new \Portier\Client\MemoryStore(),
@@ -19,30 +19,30 @@
1919
while (($line = fgets($stdin, 4096)) !== false) {
2020
$cmd = explode("\t", trim($line));
2121
switch ($cmd[0]) {
22-
case 'echo':
23-
echo "ok\t{$cmd[1]}\n";
24-
break;
25-
case 'auth':
26-
try {
27-
$authUrl = $client->authenticate($cmd[1]);
28-
echo "ok\t{$authUrl}\n";
29-
} catch (Throwable $err) {
30-
$msg = implode(" ", explode("\n", $err->getMessage()));
31-
echo "err\t{$msg}\n";
32-
}
33-
break;
34-
case 'verify':
35-
try {
36-
$email = $client->verify($cmd[1]);
37-
echo "ok\t{$email}\n";
38-
} catch (Throwable $err) {
39-
$msg = implode(" ", explode("\n", $err->getMessage()));
40-
echo "err\t{$msg}\n";
41-
}
42-
break;
43-
default:
44-
error_log("invalid command: {$cmd[0]}");
45-
exit(1);
22+
case 'echo':
23+
echo "ok\t{$cmd[1]}\n";
24+
break;
25+
case 'auth':
26+
try {
27+
$authUrl = $client->authenticate($cmd[1], $cmd[2] ?? '');
28+
echo "ok\t{$authUrl}\n";
29+
} catch (Throwable $err) {
30+
$msg = implode(' ', explode("\n", $err->getMessage()));
31+
echo "err\t{$msg}\n";
32+
}
33+
break;
34+
case 'verify':
35+
try {
36+
$email = $client->verify($cmd[1]);
37+
echo "ok\t{$email}\n";
38+
} catch (Throwable $err) {
39+
$msg = implode(' ', explode("\n", $err->getMessage()));
40+
echo "err\t{$msg}\n";
41+
}
42+
break;
43+
default:
44+
error_log("invalid command: {$cmd[0]}");
45+
exit(1);
4646
}
4747
}
4848
if (!feof($stdin)) {

src/Client.php

+8-4
Original file line numberDiff line numberDiff line change
@@ -97,28 +97,32 @@ public static function normalize(string $email): string
9797
* Start authentication of an email address.
9898
*
9999
* @param string $email email address to authenticate
100+
* @param string $state arbitrary state that is returned to the redirect URL via the `state` query parmmeter
100101
*
101102
* @return string URL to redirect the browser to
102103
*/
103-
public function authenticate(string $email): string
104+
public function authenticate(string $email, string $state = null): string
104105
{
105106
$authEndpoint = $this->fetchDiscovery()->authorization_endpoint ?? null;
106107
if (!is_string($authEndpoint)) {
107108
throw new \Exception('No authorization_endpoint in discovery document');
108109
}
109110

110111
$nonce = $this->store->createNonce($email);
111-
$query = http_build_query([
112+
$query = [
112113
'login_hint' => $email,
113114
'scope' => 'openid email',
114115
'nonce' => $nonce,
115116
'response_type' => 'id_token',
116117
'response_mode' => 'form_post',
117118
'client_id' => $this->clientId,
118119
'redirect_uri' => $this->redirectUri,
119-
]);
120+
];
121+
if (null !== $state) {
122+
$query['state'] = $state;
123+
}
120124

121-
return $authEndpoint.'?'.$query;
125+
return $authEndpoint.'?'.http_build_query($query);
122126
}
123127

124128
/**

0 commit comments

Comments
 (0)