1212
1313class JWTUtils
1414{
15+ const RSA_ALG = 'RS256 ' ;
16+
1517 /**
1618 * Composes a JWT to be used as a bearer token for authentication with Gigya
1719 *
@@ -31,21 +33,22 @@ public static function getBearerToken(string $privateKey, string $userKey, strin
3133 'jti ' => $ jti ,
3234 ];
3335
34- return JWT ::encode ($ payload , $ privateKey , ' RS256 ' , $ userKey );
36+ return JWT ::encode ($ payload , $ privateKey , self :: RSA_ALG , $ userKey );
3537 }
3638
3739 /**
3840 * Validates JWT signature
3941 *
40- * @param string $jwt
41- * @param string $apiKey
42- * @param string $apiDomain
42+ * @param string $jwt The JWT to validate
43+ * @param string $apiKey The API key of the site where the JWT is being validated
44+ * @param string $apiDomain The API domain (data center) where the site is located. For global sites, use the primary data center.
45+ * @param bool $ignoreCache If set to true, it will always contact Gigya in order to get the RSA public key. This could slow down performance considerably, and should not be used in production environments.
4346 *
4447 * @return stdClass|false
4548 *
4649 * @throws Exception
4750 */
48- public static function validateSignature (string $ jwt , string $ apiKey , string $ apiDomain ): stdClass |false
51+ public static function validateSignature (string $ jwt , string $ apiKey , string $ apiDomain, bool $ ignoreCache = false ): stdClass |false
4952 {
5053 /* Validate input and get KID */
5154 if (!$ jwt ) {
@@ -63,15 +66,14 @@ public static function validateSignature(string $jwt, string $apiKey, string $ap
6366 }
6467
6568 try {
66- $ jwk = self ::getJWKByKid ($ apiKey , $ apiDomain , $ kid );
69+ $ jwk = self ::getJWKByKid ($ apiKey , $ apiDomain , $ kid, $ ignoreCache );
6770 } catch (GSException $ e ) {
6871 return false ;
6972 }
7073
7174 try {
72- JWT ::$ leeway = 5 ;
73- $ jwtInfo = JWT ::decode ($ jwt , new Key ($ jwk , 'RS256 ' ));
74- return $ jwtInfo ?? false ;
75+ JWT ::$ leeway = 5 ;
76+ return JWT ::decode ($ jwt , $ jwk );
7577 } catch (UnexpectedValueException $ e ) {
7678 return false ;
7779 }
@@ -81,20 +83,24 @@ public static function validateSignature(string $jwt, string $apiKey, string $ap
8183 * @param string $apiKey
8284 * @param string $apiDomain
8385 * @param string $kid
86+ * @param bool $ignoreCache
8487 *
8588 * @return Key|false
8689 *
8790 * @throws GSException
8891 */
89- private static function getJWKByKid (string $ apiKey , string $ apiDomain , string $ kid ): Key |false {
90- if (($ jwks = self ::readPublicKeyCache ($ apiDomain )) === false ) {
91- $ jwks = self ::fetchPublicJWKs ($ apiKey , $ apiDomain );
92+ private static function getJWKByKid (string $ apiKey , string $ apiDomain , string $ kid , bool $ ignoreCache = false ): Key |false {
93+ if (!$ ignoreCache ) {
94+ $ jwks = self ::readPublicKeyCache ($ apiDomain );
95+ if ($ jwks === false ) {
96+ $ jwks = self ::fetchPublicJWKs ($ apiKey , $ apiDomain , $ ignoreCache );
97+ }
9298 }
9399
94100 if (isset ($ jwks [$ kid ])) {
95101 $ jwk = $ jwks [$ kid ];
96102 } else {
97- $ jwks = self ::fetchPublicJWKs ($ apiKey , $ apiDomain );
103+ $ jwks = self ::fetchPublicJWKs ($ apiKey , $ apiDomain, $ ignoreCache );
98104
99105 if (isset ($ jwks [$ kid ])) {
100106 $ jwk = $ jwks [$ kid ];
@@ -109,12 +115,13 @@ private static function getJWKByKid(string $apiKey, string $apiDomain, string $k
109115 /**
110116 * @param string $apiKey
111117 * @param string $apiDomain
118+ * @param bool $ignoreCache
112119 *
113120 * @return array<string, Key>|null
114121 *
115122 * @throws GSException
116123 */
117- private static function fetchPublicJWKs (string $ apiKey , string $ apiDomain ): array |null
124+ private static function fetchPublicJWKs (string $ apiKey , string $ apiDomain, bool $ ignoreCache = false ): array |null
118125 {
119126 $ request = new GSRequest ($ apiKey , null , 'accounts.getJWTPublicKey ' );
120127 $ request ->setAPIDomain ($ apiDomain );
@@ -130,7 +137,9 @@ private static function fetchPublicJWKs(string $apiKey, string $apiDomain): arra
130137 throw new GSException ('Unable to retrieve public key: ' . $ e ->getMessage ());
131138 }
132139
133- self ::addToPublicKeyCache ($ publicKeys , $ apiDomain );
140+ if (!$ ignoreCache ) {
141+ self ::addToPublicKeyCache ($ publicKeys , $ apiDomain );
142+ }
134143
135144 return $ publicKeys ;
136145 }
@@ -139,8 +148,8 @@ private static function fetchPublicJWKs(string $apiKey, string $apiDomain): arra
139148 }
140149
141150 /**
142- * @param array<Key> $publicKeys
143- * @param string $apiDomain
151+ * @param array<Key> $publicKeys
152+ * @param string $apiDomain
144153 *
145154 * @return int|false Bytes written to cache file or false on failure
146155 */
@@ -172,6 +181,11 @@ private static function readPublicKeyCache(string $apiDomain): array|false
172181 return false ;
173182 }
174183
175- return json_decode (file_get_contents ($ filename ), true );
184+ $ jwks = json_decode (file_get_contents ($ filename ), true );
185+ array_walk ($ jwks , function (&$ jwk ) {
186+ $ jwk = new Key ($ jwk , self ::RSA_ALG );
187+ });
188+
189+ return $ jwks ;
176190 }
177191}
0 commit comments