Skip to content

Commit 175edf9

Browse files
authored
feat: add payload to jwt exception (#521)
1 parent 5dbc895 commit 175edf9

5 files changed

+87
-5
lines changed

src/BeforeValidException.php

+12-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
namespace Firebase\JWT;
44

5-
class BeforeValidException extends \UnexpectedValueException
5+
class BeforeValidException extends \UnexpectedValueException implements JWTExceptionWithPayloadInterface
66
{
7+
private object $payload;
8+
9+
public function setPayload(object $payload): void
10+
{
11+
$this->payload = $payload;
12+
}
13+
14+
public function getPayload(): object
15+
{
16+
return $this->payload;
17+
}
718
}

src/ExpiredException.php

+12-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
namespace Firebase\JWT;
44

5-
class ExpiredException extends \UnexpectedValueException
5+
class ExpiredException extends \UnexpectedValueException implements JWTExceptionWithPayloadInterface
66
{
7+
private object $payload;
8+
9+
public function setPayload(object $payload): void
10+
{
11+
$this->payload = $payload;
12+
}
13+
14+
public function getPayload(): object
15+
{
16+
return $this->payload;
17+
}
718
}

src/JWT.php

+9-3
Original file line numberDiff line numberDiff line change
@@ -153,23 +153,29 @@ public static function decode(
153153
// Check the nbf if it is defined. This is the time that the
154154
// token can actually be used. If it's not yet that time, abort.
155155
if (isset($payload->nbf) && floor($payload->nbf) > ($timestamp + static::$leeway)) {
156-
throw new BeforeValidException(
156+
$ex = new BeforeValidException(
157157
'Cannot handle token with nbf prior to ' . \date(DateTime::ISO8601, (int) $payload->nbf)
158158
);
159+
$ex->setPayload($payload);
160+
throw $ex;
159161
}
160162

161163
// Check that this token has been created before 'now'. This prevents
162164
// using tokens that have been created for later use (and haven't
163165
// correctly used the nbf claim).
164166
if (!isset($payload->nbf) && isset($payload->iat) && floor($payload->iat) > ($timestamp + static::$leeway)) {
165-
throw new BeforeValidException(
167+
$ex = new BeforeValidException(
166168
'Cannot handle token with iat prior to ' . \date(DateTime::ISO8601, (int) $payload->iat)
167169
);
170+
$ex->setPayload($payload);
171+
throw $ex;
168172
}
169173

170174
// Check if this token has expired.
171175
if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
172-
throw new ExpiredException('Expired token');
176+
$ex = new ExpiredException('Expired token');
177+
$ex->setPayload($payload);
178+
throw $ex;
173179
}
174180

175181
return $payload;
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
namespace Firebase\JWT;
3+
4+
interface JWTExceptionWithPayloadInterface
5+
{
6+
/**
7+
* Get the payload that caused this exception.
8+
*
9+
* @return object
10+
*/
11+
public function getPayload(): object;
12+
13+
/**
14+
* Get the payload that caused this exception.
15+
*
16+
* @param object $payload
17+
* @return void
18+
*/
19+
public function setPayload(object $payload): void;
20+
}

tests/JWTTest.php

+34
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,40 @@ public function testExpiredTokenWithLeeway()
107107
$this->assertSame($decoded->message, 'abc');
108108
}
109109

110+
public function testExpiredExceptionPayload()
111+
{
112+
$this->expectException(ExpiredException::class);
113+
$payload = [
114+
'message' => 'abc',
115+
'exp' => time() - 100, // time in the past
116+
];
117+
$encoded = JWT::encode($payload, 'my_key', 'HS256');
118+
try {
119+
JWT::decode($encoded, new Key('my_key', 'HS256'));
120+
} catch (ExpiredException $e) {
121+
$exceptionPayload = (array) $e->getPayload();
122+
$this->assertEquals($exceptionPayload, $payload);
123+
throw $e;
124+
}
125+
}
126+
127+
public function testBeforeValidExceptionPayload()
128+
{
129+
$this->expectException(BeforeValidException::class);
130+
$payload = [
131+
'message' => 'abc',
132+
'iat' => time() + 100, // time in the future
133+
];
134+
$encoded = JWT::encode($payload, 'my_key', 'HS256');
135+
try {
136+
JWT::decode($encoded, new Key('my_key', 'HS256'));
137+
} catch (BeforeValidException $e) {
138+
$exceptionPayload = (array) $e->getPayload();
139+
$this->assertEquals($exceptionPayload, $payload);
140+
throw $e;
141+
}
142+
}
143+
110144
public function testValidTokenWithNbf()
111145
{
112146
$payload = [

0 commit comments

Comments
 (0)