Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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