-
-
Notifications
You must be signed in to change notification settings - Fork 452
Expand file tree
/
Copy pathCustomTokenViaGoogleCredentials.php
More file actions
86 lines (71 loc) · 2.51 KB
/
CustomTokenViaGoogleCredentials.php
File metadata and controls
86 lines (71 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php
declare(strict_types=1);
namespace Kreait\Firebase\Auth;
use DateInterval;
use DateTimeImmutable;
use DateTimeInterface;
use Google\Auth\SignBlobInterface;
use Kreait\Firebase\Exception\Auth\AuthError;
use Kreait\Firebase\Util\DT;
use Lcobucci\JWT\Encoding\JoseEncoder;
use Lcobucci\JWT\Token;
use Lcobucci\JWT\Token\Parser;
use Stringable;
/**
* @internal
*/
final class CustomTokenViaGoogleCredentials
{
private readonly JoseEncoder $encoder;
private readonly Parser $parser;
public function __construct(
private readonly SignBlobInterface $signer,
private readonly ?string $tenantId = null,
private readonly ?string $serviceAccountIdForTokenGeneration = null,
)
{
$this->encoder = new JoseEncoder();
$this->parser = new Parser($this->encoder);
}
/**
* @param Stringable|string $uid
* @param array<non-empty-string, mixed> $claims
*
* @throws AuthError
*/
public function createCustomToken($uid, array $claims = [], ?DateTimeInterface $expiresAt = null): Token
{
$now = new DateTimeImmutable();
$expiresAt = ($expiresAt !== null)
? DT::toUTCDateTimeImmutable($expiresAt)
: $now->add(new DateInterval('PT1H'));
$issAndSub = $this->serviceAccountIdForTokenGeneration ?? $this->signer->getClientName();
$header = ['typ' => 'JWT', 'alg' => 'RS256'];
$payload = [
'iss' => $issAndSub,
'sub' => $issAndSub,
'aud' => 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',
'iat' => $now->getTimestamp(),
'exp' => $expiresAt->getTimestamp(),
'uid' => (string) $uid,
];
if ($this->tenantId !== null) {
$payload['tenant_id'] = $this->tenantId;
}
if ($claims !== []) {
$payload['claims'] = $claims;
}
$base64UrlHeader = $this->base64EncodeArray($header);
$base64UrlPayload = $this->base64EncodeArray($payload);
$signature = $this->signer->signBlob($base64UrlHeader.'.'.$base64UrlPayload);
$signature = str_replace(['=', '+', '/'], ['', '-', '_'], $signature);
return $this->parser->parse(sprintf('%s.%s.%s', $base64UrlHeader, $base64UrlPayload, $signature));
}
/**
* @param array<mixed> $array
*/
private function base64EncodeArray(array $array): string
{
return $this->encoder->base64UrlEncode($this->encoder->jsonEncode($array));
}
}