Subversion-Projekte lars-tiefland.laravel_shop

Revision

Zur aktuellen Revision | Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Foundation\Http\Middleware;
4
 
5
use Closure;
6
use Illuminate\Contracts\Encryption\DecryptException;
7
use Illuminate\Contracts\Encryption\Encrypter;
8
use Illuminate\Contracts\Foundation\Application;
9
use Illuminate\Contracts\Support\Responsable;
10
use Illuminate\Cookie\CookieValuePrefix;
11
use Illuminate\Cookie\Middleware\EncryptCookies;
12
use Illuminate\Session\TokenMismatchException;
13
use Illuminate\Support\InteractsWithTime;
14
use Symfony\Component\HttpFoundation\Cookie;
15
 
16
class VerifyCsrfToken
17
{
18
    use InteractsWithTime;
19
 
20
    /**
21
     * The application instance.
22
     *
23
     * @var \Illuminate\Contracts\Foundation\Application
24
     */
25
    protected $app;
26
 
27
    /**
28
     * The encrypter implementation.
29
     *
30
     * @var \Illuminate\Contracts\Encryption\Encrypter
31
     */
32
    protected $encrypter;
33
 
34
    /**
35
     * The URIs that should be excluded from CSRF verification.
36
     *
37
     * @var array
38
     */
39
    protected $except = [];
40
 
41
    /**
42
     * Indicates whether the XSRF-TOKEN cookie should be set on the response.
43
     *
44
     * @var bool
45
     */
46
    protected $addHttpCookie = true;
47
 
48
    /**
49
     * Create a new middleware instance.
50
     *
51
     * @param  \Illuminate\Contracts\Foundation\Application  $app
52
     * @param  \Illuminate\Contracts\Encryption\Encrypter  $encrypter
53
     * @return void
54
     */
55
    public function __construct(Application $app, Encrypter $encrypter)
56
    {
57
        $this->app = $app;
58
        $this->encrypter = $encrypter;
59
    }
60
 
61
    /**
62
     * Handle an incoming request.
63
     *
64
     * @param  \Illuminate\Http\Request  $request
65
     * @param  \Closure  $next
66
     * @return mixed
67
     *
68
     * @throws \Illuminate\Session\TokenMismatchException
69
     */
70
    public function handle($request, Closure $next)
71
    {
72
        if (
73
            $this->isReading($request) ||
74
            $this->runningUnitTests() ||
75
            $this->inExceptArray($request) ||
76
            $this->tokensMatch($request)
77
        ) {
78
            return tap($next($request), function ($response) use ($request) {
79
                if ($this->shouldAddXsrfTokenCookie()) {
80
                    $this->addCookieToResponse($request, $response);
81
                }
82
            });
83
        }
84
 
85
        throw new TokenMismatchException('CSRF token mismatch.');
86
    }
87
 
88
    /**
89
     * Determine if the HTTP request uses a ‘read’ verb.
90
     *
91
     * @param  \Illuminate\Http\Request  $request
92
     * @return bool
93
     */
94
    protected function isReading($request)
95
    {
96
        return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS']);
97
    }
98
 
99
    /**
100
     * Determine if the application is running unit tests.
101
     *
102
     * @return bool
103
     */
104
    protected function runningUnitTests()
105
    {
106
        return $this->app->runningInConsole() && $this->app->runningUnitTests();
107
    }
108
 
109
    /**
110
     * Determine if the request has a URI that should pass through CSRF verification.
111
     *
112
     * @param  \Illuminate\Http\Request  $request
113
     * @return bool
114
     */
115
    protected function inExceptArray($request)
116
    {
117
        foreach ($this->except as $except) {
118
            if ($except !== '/') {
119
                $except = trim($except, '/');
120
            }
121
 
122
            if ($request->fullUrlIs($except) || $request->is($except)) {
123
                return true;
124
            }
125
        }
126
 
127
        return false;
128
    }
129
 
130
    /**
131
     * Determine if the session and input CSRF tokens match.
132
     *
133
     * @param  \Illuminate\Http\Request  $request
134
     * @return bool
135
     */
136
    protected function tokensMatch($request)
137
    {
138
        $token = $this->getTokenFromRequest($request);
139
 
140
        return is_string($request->session()->token()) &&
141
               is_string($token) &&
142
               hash_equals($request->session()->token(), $token);
143
    }
144
 
145
    /**
146
     * Get the CSRF token from the request.
147
     *
148
     * @param  \Illuminate\Http\Request  $request
149
     * @return string|null
150
     */
151
    protected function getTokenFromRequest($request)
152
    {
153
        $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');
154
 
155
        if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
156
            try {
157
                $token = CookieValuePrefix::remove($this->encrypter->decrypt($header, static::serialized()));
158
            } catch (DecryptException $e) {
159
                $token = '';
160
            }
161
        }
162
 
163
        return $token;
164
    }
165
 
166
    /**
167
     * Determine if the cookie should be added to the response.
168
     *
169
     * @return bool
170
     */
171
    public function shouldAddXsrfTokenCookie()
172
    {
173
        return $this->addHttpCookie;
174
    }
175
 
176
    /**
177
     * Add the CSRF token to the response cookies.
178
     *
179
     * @param  \Illuminate\Http\Request  $request
180
     * @param  \Symfony\Component\HttpFoundation\Response  $response
181
     * @return \Symfony\Component\HttpFoundation\Response
182
     */
183
    protected function addCookieToResponse($request, $response)
184
    {
185
        $config = config('session');
186
 
187
        if ($response instanceof Responsable) {
188
            $response = $response->toResponse($request);
189
        }
190
 
191
        $response->headers->setCookie($this->newCookie($request, $config));
192
 
193
        return $response;
194
    }
195
 
196
    /**
197
     * Create a new "XSRF-TOKEN" cookie that contains the CSRF token.
198
     *
199
     * @param  \Illuminate\Http\Request  $request
200
     * @param  array  $config
201
     * @return \Symfony\Component\HttpFoundation\Cookie
202
     */
203
    protected function newCookie($request, $config)
204
    {
205
        return new Cookie(
206
            'XSRF-TOKEN',
207
            $request->session()->token(),
208
            $this->availableAt(60 * $config['lifetime']),
209
            $config['path'],
210
            $config['domain'],
211
            $config['secure'],
212
            false,
213
            false,
214
            $config['same_site'] ?? null
215
        );
216
    }
217
 
218
    /**
219
     * Determine if the cookie contents should be serialized.
220
     *
221
     * @return bool
222
     */
223
    public static function serialized()
224
    {
225
        return EncryptCookies::serialized('XSRF-TOKEN');
226
    }
227
}