|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* Token |
|
5
|
|
|
* |
|
6
|
|
|
* A JWT implementation |
|
7
|
|
|
* http://openid.net/specs/draft-jones-json-web-token-07.html |
|
8
|
|
|
* |
|
9
|
|
|
* @package core |
|
10
|
|
|
* @author [email protected] |
|
11
|
|
|
* @copyright Caffeina srl - 2015 - http://caffeina.it |
|
12
|
|
|
*/ |
|
13
|
|
|
|
|
14
|
|
|
class Token { |
|
15
|
|
|
|
|
16
|
|
|
public static function encode($payload, $secret, $algo = 'HS256') { |
|
17
|
|
|
$encoded_payload = implode('.', [rtrim(strtr(base64_encode(json_encode([ |
|
18
|
|
|
'typ' => 'JWT', |
|
19
|
|
|
'alg' => $algo, |
|
20
|
|
|
])), '+/', '-_'),'='), |
|
21
|
|
|
rtrim(strtr(base64_encode(json_encode($payload)), '+/', '-_'),'='), |
|
22
|
|
|
]); |
|
23
|
|
|
return $encoded_payload . '.' . static::sign($encoded_payload, $secret, $algo); |
|
24
|
|
|
} |
|
25
|
|
|
|
|
26
|
|
|
public static function decode($jwt, $secret = null, $verify = true){ |
|
27
|
|
|
|
|
28
|
|
|
if (substr_count($jwt,'.') != 2) throw new \Exception('Token not valid'); |
|
29
|
|
|
|
|
30
|
|
|
list($encoded_header, $encoded_payload, $client_sig) = explode('.', $jwt); |
|
31
|
|
|
|
|
32
|
|
View Code Duplication |
if (null === ($payload = json_decode(base64_decode(strtr($encoded_payload, '-_', '+/'))))) |
|
33
|
|
|
throw new \Exception('Invalid encoding'); |
|
34
|
|
|
|
|
35
|
|
|
|
|
36
|
|
|
if ($verify) { |
|
37
|
|
View Code Duplication |
if (null === ($header = json_decode(base64_decode(strtr($encoded_header, '-_', '+/'))))) |
|
38
|
|
|
throw new \Exception('Invalid encoding'); |
|
39
|
|
|
|
|
40
|
|
|
if (empty($header->alg)) throw new \Exception('Invalid encoding'); |
|
41
|
|
|
|
|
42
|
|
|
if ($client_sig != static::sign("$encoded_header.$encoded_payload", $secret, $header->alg)) |
|
43
|
|
|
throw new \Exception('Token verification failed'); |
|
44
|
|
|
} |
|
45
|
|
|
|
|
46
|
|
|
return $payload; |
|
47
|
|
|
} |
|
48
|
|
|
|
|
49
|
|
|
protected static function sign($payload, $secret, $algo = 'HS256') { |
|
50
|
|
|
$algos = [ |
|
51
|
|
|
'HS512' => 'sha512', |
|
52
|
|
|
'HS384' => 'sha384', |
|
53
|
|
|
'HS256' => 'sha256', |
|
54
|
|
|
]; |
|
55
|
|
|
if (empty($algos[$algo])) throw new \Exception('Signing algorithm not supported'); |
|
56
|
|
|
return rtrim(strtr(base64_encode(hash_hmac($algos[$algo], $payload, $secret, true)), '+/', '-_'),'='); |
|
57
|
|
|
} |
|
58
|
|
|
|
|
59
|
|
|
} |
|
60
|
|
|
|