Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 59
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
JWT
0.00% covered (danger)
0.00%
0 / 59
0.00% covered (danger)
0.00%
0 / 8
650
0.00% covered (danger)
0.00%
0 / 1
 decode
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
56
 encode
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 sign
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 jsonDecode
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
30
 jsonEncode
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
30
 urlsafeB64Decode
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 urlsafeB64Encode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 _handleJsonError
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * JSON Web Token implementation, based on this spec:
4 * http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
5 *
6 * PHP version 5
7 *
8 * @category Authentication
9 * @package  Authentication_JWT
10 * @author   Neuman Vong <neuman@twilio.com>
11 * @author   Anant Narayanan <anant@php.net>
12 * @license  http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
13 * @link     https://github.com/firebase/php-jwt
14 */
15class JWT
16{
17    /**
18     * Decodes a JWT string into a PHP object.
19     *
20     * @param string      $jwt    The JWT
21     * @param string|null $key    The secret key
22     * @param bool        $verify Don't skip verification process
23     *
24     * @return object      The JWT's payload as a PHP object
25     * @throws UnexpectedValueException Provided JWT was invalid
26     * @throws DomainException          Algorithm was not provided
27     *
28     * @uses jsonDecode
29     * @uses urlsafeB64Decode
30     */
31    public static function decode($jwt, $key = null, $verify = true)
32    {
33        $tks = explode('.', $jwt);
34        if (count($tks) != 3) {
35            throw new UnexpectedValueException('Wrong number of segments');
36        }
37        list($headb64, $bodyb64, $cryptob64) = $tks;
38        if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) {
39            throw new UnexpectedValueException('Invalid segment encoding');
40        }
41        if (null === $payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64))) {
42            throw new UnexpectedValueException('Invalid segment encoding');
43        }
44        $sig = JWT::urlsafeB64Decode($cryptob64);
45        if ($verify) {
46            if (empty($header->alg)) {
47                throw new DomainException('Empty algorithm');
48            }
49            if ($sig != JWT::sign("$headb64.$bodyb64", $key, $header->alg)) {
50                throw new UnexpectedValueException('Signature verification failed');
51            }
52        }
53        return $payload;
54    }
55    /**
56     * Converts and signs a PHP object or array into a JWT string.
57     *
58     * @param object|array $payload PHP object or array
59     * @param string       $key     The secret key
60     * @param string       $algo    The signing algorithm. Supported
61     *                              algorithms are 'HS256', 'HS384' and 'HS512'
62     *
63     * @return string      A signed JWT
64     * @uses jsonEncode
65     * @uses urlsafeB64Encode
66     */
67    public static function encode($payload, $key, $algo = 'HS256')
68    {
69        $header = array('typ' => 'JWT', 'alg' => $algo);
70        $segments = array();
71        $segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($header));
72        $segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($payload));
73        $signing_input = implode('.', $segments);
74        $signature = JWT::sign($signing_input, $key, $algo);
75        $segments[] = JWT::urlsafeB64Encode($signature);
76        return implode('.', $segments);
77    }
78    /**
79     * Sign a string with a given key and algorithm.
80     *
81     * @param string $msg    The message to sign
82     * @param string $key    The secret key
83     * @param string $method The signing algorithm. Supported
84     *                       algorithms are 'HS256', 'HS384' and 'HS512'
85     *
86     * @return string          An encrypted message
87     * @throws DomainException Unsupported algorithm was specified
88     */
89    public static function sign($msg, $key, $method = 'HS256')
90    {
91        $methods = array(
92            'HS256' => 'sha256',
93            'HS384' => 'sha384',
94            'HS512' => 'sha512',
95        );
96        if (empty($methods[$method])) {
97            throw new DomainException('Algorithm not supported');
98        }
99        return hash_hmac($methods[$method], $msg, $key, true);
100    }
101    /**
102     * Decode a JSON string into a PHP object.
103     *
104     * @param string $input JSON string
105     *
106     * @return object          Object representation of JSON string
107     * @throws DomainException Provided string was invalid JSON
108     */
109    public static function jsonDecode($input)
110    {
111        $obj = json_decode($input);
112        if (function_exists('json_last_error') && $errno = json_last_error()) {
113            JWT::_handleJsonError($errno);
114        } else if ($obj === null && $input !== 'null') {
115            throw new DomainException('Null result with non-null input');
116        }
117        return $obj;
118    }
119    /**
120     * Encode a PHP object into a JSON string.
121     *
122     * @param object|array $input A PHP object or array
123     *
124     * @return string          JSON representation of the PHP object or array
125     * @throws DomainException Provided object could not be encoded to valid JSON
126     */
127    public static function jsonEncode($input)
128    {
129        $json = json_encode($input);
130        if (function_exists('json_last_error') && $errno = json_last_error()) {
131            JWT::_handleJsonError($errno);
132        } else if ($json === 'null' && $input !== null) {
133            throw new DomainException('Null result with non-null input');
134        }
135        return $json;
136    }
137    /**
138     * Decode a string with URL-safe Base64.
139     *
140     * @param string $input A Base64 encoded string
141     *
142     * @return string A decoded string
143     */
144    public static function urlsafeB64Decode($input)
145    {
146        $remainder = strlen($input) % 4;
147        if ($remainder) {
148            $padlen = 4 - $remainder;
149            $input .= str_repeat('=', $padlen);
150        }
151        return base64_decode(strtr($input, '-_', '+/'));
152    }
153    /**
154     * Encode a string with URL-safe Base64.
155     *
156     * @param string $input The string you want encoded
157     *
158     * @return string The base64 encode of what you passed in
159     */
160    public static function urlsafeB64Encode($input)
161    {
162        return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
163    }
164    /**
165     * Helper method to create a JSON error.
166     *
167     * @param int $errno An error number from json_last_error()
168     *
169     * @return void
170     */
171    private static function _handleJsonError($errno)
172    {
173        $messages = array(
174            JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
175            JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
176            JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON'
177        );
178        throw new DomainException(
179            isset($messages[$errno])
180                ? $messages[$errno]
181                : 'Unknown JSON error: ' . $errno
182        );
183    }
184}