Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 * This file is part of the Symfony package.
|
Chris@0
|
5 *
|
Chris@0
|
6 * (c) Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
7 *
|
Chris@0
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
9 * file that was distributed with this source code.
|
Chris@0
|
10 */
|
Chris@0
|
11
|
Chris@0
|
12 namespace Symfony\Component\HttpKernel;
|
Chris@0
|
13
|
Chris@0
|
14 /**
|
Chris@0
|
15 * Signs URIs.
|
Chris@0
|
16 *
|
Chris@0
|
17 * @author Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
18 */
|
Chris@0
|
19 class UriSigner
|
Chris@0
|
20 {
|
Chris@0
|
21 private $secret;
|
Chris@14
|
22 private $parameter;
|
Chris@0
|
23
|
Chris@0
|
24 /**
|
Chris@14
|
25 * @param string $secret A secret
|
Chris@14
|
26 * @param string $parameter Query string parameter to use
|
Chris@0
|
27 */
|
Chris@14
|
28 public function __construct($secret, $parameter = '_hash')
|
Chris@0
|
29 {
|
Chris@0
|
30 $this->secret = $secret;
|
Chris@14
|
31 $this->parameter = $parameter;
|
Chris@0
|
32 }
|
Chris@0
|
33
|
Chris@0
|
34 /**
|
Chris@0
|
35 * Signs a URI.
|
Chris@0
|
36 *
|
Chris@14
|
37 * The given URI is signed by adding the query string parameter
|
Chris@0
|
38 * which value depends on the URI and the secret.
|
Chris@0
|
39 *
|
Chris@0
|
40 * @param string $uri A URI to sign
|
Chris@0
|
41 *
|
Chris@0
|
42 * @return string The signed URI
|
Chris@0
|
43 */
|
Chris@0
|
44 public function sign($uri)
|
Chris@0
|
45 {
|
Chris@0
|
46 $url = parse_url($uri);
|
Chris@0
|
47 if (isset($url['query'])) {
|
Chris@0
|
48 parse_str($url['query'], $params);
|
Chris@0
|
49 } else {
|
Chris@17
|
50 $params = [];
|
Chris@0
|
51 }
|
Chris@0
|
52
|
Chris@0
|
53 $uri = $this->buildUrl($url, $params);
|
Chris@17
|
54 $params[$this->parameter] = $this->computeHash($uri);
|
Chris@0
|
55
|
Chris@17
|
56 return $this->buildUrl($url, $params);
|
Chris@0
|
57 }
|
Chris@0
|
58
|
Chris@0
|
59 /**
|
Chris@0
|
60 * Checks that a URI contains the correct hash.
|
Chris@0
|
61 *
|
Chris@0
|
62 * @param string $uri A signed URI
|
Chris@0
|
63 *
|
Chris@0
|
64 * @return bool True if the URI is signed correctly, false otherwise
|
Chris@0
|
65 */
|
Chris@0
|
66 public function check($uri)
|
Chris@0
|
67 {
|
Chris@0
|
68 $url = parse_url($uri);
|
Chris@0
|
69 if (isset($url['query'])) {
|
Chris@0
|
70 parse_str($url['query'], $params);
|
Chris@0
|
71 } else {
|
Chris@17
|
72 $params = [];
|
Chris@0
|
73 }
|
Chris@0
|
74
|
Chris@14
|
75 if (empty($params[$this->parameter])) {
|
Chris@0
|
76 return false;
|
Chris@0
|
77 }
|
Chris@0
|
78
|
Chris@17
|
79 $hash = $params[$this->parameter];
|
Chris@14
|
80 unset($params[$this->parameter]);
|
Chris@0
|
81
|
Chris@0
|
82 return $this->computeHash($this->buildUrl($url, $params)) === $hash;
|
Chris@0
|
83 }
|
Chris@0
|
84
|
Chris@0
|
85 private function computeHash($uri)
|
Chris@0
|
86 {
|
Chris@17
|
87 return base64_encode(hash_hmac('sha256', $uri, $this->secret, true));
|
Chris@0
|
88 }
|
Chris@0
|
89
|
Chris@17
|
90 private function buildUrl(array $url, array $params = [])
|
Chris@0
|
91 {
|
Chris@0
|
92 ksort($params, SORT_STRING);
|
Chris@0
|
93 $url['query'] = http_build_query($params, '', '&');
|
Chris@0
|
94
|
Chris@0
|
95 $scheme = isset($url['scheme']) ? $url['scheme'].'://' : '';
|
Chris@0
|
96 $host = isset($url['host']) ? $url['host'] : '';
|
Chris@0
|
97 $port = isset($url['port']) ? ':'.$url['port'] : '';
|
Chris@0
|
98 $user = isset($url['user']) ? $url['user'] : '';
|
Chris@0
|
99 $pass = isset($url['pass']) ? ':'.$url['pass'] : '';
|
Chris@0
|
100 $pass = ($user || $pass) ? "$pass@" : '';
|
Chris@0
|
101 $path = isset($url['path']) ? $url['path'] : '';
|
Chris@0
|
102 $query = isset($url['query']) && $url['query'] ? '?'.$url['query'] : '';
|
Chris@0
|
103 $fragment = isset($url['fragment']) ? '#'.$url['fragment'] : '';
|
Chris@0
|
104
|
Chris@0
|
105 return $scheme.$user.$pass.$host.$port.$path.$query.$fragment;
|
Chris@0
|
106 }
|
Chris@0
|
107 }
|