1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Jasny\Auth\Session; |
6
|
|
|
|
7
|
|
|
use Jasny\Auth\Session\Jwt\Cookie; |
8
|
|
|
use Jasny\Auth\Session\Jwt\CookieInterface; |
9
|
|
|
use Jasny\Immutable; |
10
|
|
|
use Lcobucci\JWT\Parser; |
11
|
|
|
use Lcobucci\JWT\Builder; |
12
|
|
|
use Lcobucci\JWT\Signer; |
13
|
|
|
use Lcobucci\JWT\ValidationData; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Use JSON Web Token and JSON Web Signature (RFC 7519) to store auth session info. |
17
|
|
|
* |
18
|
|
|
* @see https://github.com/lcobucci/jwt |
19
|
|
|
*/ |
20
|
|
|
class Jwt implements SessionInterface |
21
|
|
|
{ |
22
|
|
|
use Immutable\With; |
23
|
|
|
|
24
|
|
|
protected Builder $builder; |
25
|
|
|
protected Signer $signer; |
26
|
|
|
protected Signer\Key $key; |
27
|
|
|
|
28
|
|
|
protected Parser $parser; |
29
|
|
|
protected ValidationData $validation; |
30
|
|
|
|
31
|
|
|
protected int $ttl = 24 * 3600; |
32
|
|
|
protected CookieInterface $cookie; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* JWT constructor. |
36
|
|
|
*/ |
37
|
8 |
|
public function __construct(Builder $builder, Signer $signer, Signer\Key $key, ValidationData $validation) |
38
|
|
|
{ |
39
|
8 |
|
$this->builder = $builder; |
40
|
8 |
|
$this->signer = $signer; |
41
|
8 |
|
$this->key = $key; |
42
|
|
|
|
43
|
8 |
|
$this->validation = $validation; |
44
|
8 |
|
$this->parser = new Parser(); |
45
|
|
|
|
46
|
8 |
|
$this->cookie = new Cookie('jwt'); |
47
|
8 |
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Get a copy with a different TTL for expiry. |
51
|
|
|
*/ |
52
|
1 |
|
public function withTtl(int $seconds): self |
53
|
|
|
{ |
54
|
1 |
|
return $this->withProperty('ttl', $seconds); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Get a copy with custom cookie handler. |
59
|
|
|
*/ |
60
|
8 |
|
public function withCookie(CookieInterface $cookie): self |
61
|
|
|
{ |
62
|
8 |
|
return $this->withProperty('cookie', $cookie); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* Get a copy with a custom JWT parser. |
67
|
|
|
*/ |
68
|
1 |
|
public function withParser(Parser $parser): self |
69
|
|
|
{ |
70
|
1 |
|
return $this->withProperty('parser', $parser); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* @inheritDoc |
75
|
|
|
*/ |
76
|
5 |
|
public function getInfo(): array |
77
|
|
|
{ |
78
|
5 |
|
$jwt = $this->cookie->get(); |
79
|
|
|
|
80
|
5 |
|
$token = $jwt !== null && $jwt !== '' |
81
|
4 |
|
? $this->parser->parse($jwt) |
82
|
5 |
|
: null; |
83
|
|
|
|
84
|
5 |
|
if ($token === null || !$token->validate($this->validation)) { |
|
|
|
|
85
|
2 |
|
return ['user' => null, 'context' => null, 'checksum' => null, 'timestamp' => null]; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
return [ |
89
|
3 |
|
'user' => $token->claims()->get('user'), |
90
|
3 |
|
'context' => $token->claims()->get('context'), |
91
|
3 |
|
'checksum' => $token->claims()->get('checksum'), |
92
|
3 |
|
'timestamp' => $token->headers()->get('iat'), |
93
|
|
|
]; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* @inheritDoc |
98
|
|
|
*/ |
99
|
2 |
|
public function persist($user, $context, ?string $checksum, ?\DateTimeInterface $timestamp): void |
100
|
|
|
{ |
101
|
2 |
|
$builder = clone $this->builder; |
102
|
|
|
|
103
|
2 |
|
if ($timestamp instanceof \DateTime) { |
104
|
2 |
|
$timestamp = \DateTimeImmutable::createFromMutable($timestamp); |
105
|
|
|
} |
106
|
2 |
|
$time = $timestamp ?? new \DateTimeImmutable(); |
107
|
2 |
|
$expire = $time->add(new \DateInterval("PT{$this->ttl}S")); |
|
|
|
|
108
|
|
|
|
109
|
|
|
$builder |
110
|
2 |
|
->withClaim('user', $user) |
111
|
2 |
|
->withClaim('context', $context) |
112
|
2 |
|
->withClaim('checksum', $checksum) |
113
|
2 |
|
->issuedAt($time) |
|
|
|
|
114
|
2 |
|
->expiresAt($expire); |
115
|
|
|
|
116
|
2 |
|
if ($timestamp !== null) { |
117
|
2 |
|
$builder->withHeader('iat', $timestamp); |
118
|
|
|
} |
119
|
|
|
|
120
|
2 |
|
$this->cookie->set( |
121
|
2 |
|
(string)$builder->getToken($this->signer, $this->key), |
122
|
2 |
|
$expire->getTimestamp() |
123
|
|
|
); |
124
|
2 |
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* @inheritDoc |
128
|
|
|
*/ |
129
|
1 |
|
public function clear(): void |
130
|
|
|
{ |
131
|
1 |
|
$this->cookie->clear(); |
132
|
1 |
|
} |
133
|
|
|
} |
134
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.