@@ -43,18 +43,14 @@ class JWT
4343 */
4444 public static function decode ($ jwt , $ key = null , $ verify = true )
4545 {
46- $ tks = explode ('. ' , $ jwt );
47- if (count ($ tks ) != 3 ) {
48- throw new UnexpectedValueException ('Wrong number of segments ' );
49- }
50- list ($ headb64 , $ bodyb64 , $ cryptob64 ) = $ tks ;
51- if (null === ($ header = JWT ::jsonDecode (JWT ::urlsafeB64Decode ($ headb64 )))) {
46+ $ tks = JWT ::split ($ jwt );
47+
48+ if (null === ($ header = JWT ::jsonDecode (JWT ::urlsafeB64Decode ($ tks ['header ' ])))) {
5249 throw new UnexpectedValueException ('Invalid header encoding ' );
5350 }
54- if (null === $ payload = JWT ::jsonDecode (JWT ::urlsafeB64Decode ($ bodyb64 ))) {
51+ if (null === $ payload = JWT ::jsonDecode (JWT ::urlsafeB64Decode ($ tks [ ' body ' ] ))) {
5552 throw new UnexpectedValueException ('Invalid claims encoding ' );
5653 }
57- $ sig = JWT ::urlsafeB64Decode ($ cryptob64 );
5854 if ($ verify ) {
5955 if (empty ($ header ->alg )) {
6056 throw new DomainException ('Empty algorithm ' );
@@ -68,7 +64,7 @@ public static function decode($jwt, $key = null, $verify = true)
6864 }
6965
7066 // Check the signature
71- if (!JWT ::verify (" $ headb64 . $ bodyb64 " , $ sig , $ key , $ header ->alg )) {
67+ if (!JWT ::verify ($ tks , $ key , $ header ->alg )) {
7268 throw new SignatureInvalidException ('Signature verification failed ' );
7369 }
7470
@@ -98,6 +94,31 @@ public static function decode($jwt, $key = null, $verify = true)
9894 return $ payload ;
9995 }
10096
97+ /**
98+ * Splits a JWT string into an array, if it isn't already split, and returns the result.
99+ *
100+ * @param object|array $payload PHP object or array
101+ * @param string|array $jwt JWT string or split tokens
102+ *
103+ * @return array A split JWT token
104+ *
105+ * @throws UnexpectedValueException Provided JWT was invalid
106+ */
107+ public static function split ($ jwt )
108+ {
109+ if (is_array ($ jwt )) {
110+ return $ jwt ;
111+ }
112+
113+ $ tks = explode ('. ' , $ jwt );
114+
115+ if (count ($ tks ) != 3 ) {
116+ throw new UnexpectedValueException ('Wrong number of segments ' );
117+ }
118+
119+ return array_combine (array ('header ' , 'body ' , 'sig ' ), $ tks );
120+ }
121+
101122 /**
102123 * Converts and signs a PHP object or array into a JWT string.
103124 *
@@ -161,18 +182,23 @@ public static function sign($msg, $key, $method = 'HS256')
161182 /**
162183 * Verify a signature with the mesage, key and method. Not all methods
163184 * are symmetric, so we must have a separate verify and sign method.
164- * @param string $msg the original message
185+ * @param string $tks the split jwt token
165186 * @param string $signature
166187 * @param string|resource $key for HS*, a string key works. for RS*, must be a resource of an openssl public key
167188 * @param string $method
168189 * @return bool
169190 * @throws DomainException Invalid Algorithm or OpenSSL failure
170191 */
171- public static function verify ($ msg , $ signature , $ key , $ method = 'HS256 ' )
192+ public static function verify ($ jwt , $ key , $ method = 'HS256 ' )
172193 {
173194 if (empty (self ::$ methods [$ method ])) {
174195 throw new DomainException ('Algorithm not supported ' );
175196 }
197+
198+ $ tks = JWT ::split ($ jwt );
199+ $ msg = $ tks ['header ' ] . '. ' . $ tks ['body ' ];
200+ $ signature = JWT ::urlsafeB64Decode ($ tks ['sig ' ]);
201+
176202 list ($ function , $ algo ) = self ::$ methods [$ method ];
177203 switch ($ function ) {
178204 case 'openssl ' :
0 commit comments