/** * Handle an incoming request. * * @param Request $request * @param \Closure $next * @return Response * @throws InvalidCsrfTokenException */ public function handle(Request $request, Closure $next) : Response { $cookieData = $request->cookie('csrfToken'); if ($cookieData) { $this->_token = $cookieData; } $createCookie = false; if ($request->method() == 'GET' and $cookieData === null) { $this->_token = hash('sha1', Text::uuid()); $createCookie = true; } if (in_array($request->method(), ['PATCH', 'PUT', 'POST', 'DELETE'])) { $post = $request->data['_csrfToken']; $header = $request->header('X-CSRF-Token'); if (empty($cookieData)) { throw new InvalidCsrfTokenException('Missing CSRF token cookie'); } if ($post !== $cookieData and $header !== $cookieData) { throw new InvalidCsrfTokenException('CSRF token mismatch'); } } $response = $next($request); if ($createCookie) { $response->cookie('csrfToken', $this->_token); } return $response; }
/** * Setup access for origin and methods on cross origin requests * * This method allow multiple ways to setup the domains, see the examples * * ### Full URI * ``` * cors($request, 'http://www.cakephp.org'); * ``` * * ### URI with wildcard * ``` * cors($request, 'http://*.cakephp.org'); * ``` * * ### Ignoring the requested protocol * ``` * cors($request, 'www.cakephp.org'); * ``` * * ### Any URI * ``` * cors($request, '*'); * ``` * * ### Whitelist of URIs * ``` * cors($request, ['http://www.cakephp.org', '*.google.com', 'https://myproject.github.io']); * ``` * * *Note* The `$allowedDomains`, `$allowedMethods`, `$allowedHeaders` parameters are deprecated. * Instead the builder object should be used. * * @param \CoreTyson\Network\Request $request Request object * @param string|array $allowedDomains List of allowed domains, see method description for more details * @param string|array $allowedMethods List of HTTP verbs allowed * @param string|array $allowedHeaders List of HTTP headers allowed * @return \CoreTyson\Network\CorsBuilder A builder object the provides a fluent interface for defining * additional CORS headers. */ public function cors(Request $request, $allowedDomains = [], $allowedMethods = [], $allowedHeaders = []) { $origin = $request->header('Origin'); $ssl = $request->is('ssl'); $builder = new CorsBuilder($this, $origin, $ssl); if (!$origin) { return $builder; } if (empty($allowedDomains) && empty($allowedMethods) && empty($allowedHeaders)) { return $builder; } $builder->allowOrigin($allowedDomains)->allowMethods((array) $allowedMethods)->allowHeaders((array) $allowedHeaders)->build(); return $builder; }
/** * Wrapper method to create a new request from PHP superglobals. * * Uses the $_GET, $_POST, $_FILES, $_COOKIE, $_SERVER ands $_ENV data to construct * the request. * * @return Request */ public static function createFromGlobals() : Request { $request = new Request(); $request->_environment = $_SERVER + $_ENV; $request->queryArgs = $_GET; $request->_bodyStream = new LazyOpenStream('php://input', 'r+'); $data = $_POST; $method = $request->env('REQUEST_METHOD'); if (in_array($method, ['PUT', 'DELETE', 'PATCH']) && strpos($request->contentType(), 'application/x-www-form-urlencoded') === 0) { $data = $request->_bodyStream->getContents(); } parse_str($data, $data); if ($request->env('HTTP_X_HTTP_METHOD_OVERRIDE')) { $data['_method'] = $request->env('HTTP_X_HTTP_METHOD_OVERRIDE'); } $request->_environment['ORIGINAL_REQUEST_METHOD'] = $method; if (isset($data['_method'])) { $request->_environment['REQUEST_METHOD'] = $data['_method']; unset($data['_method']); } $request->data = $data; $request->_cookies = $_COOKIE; $request->_uri = new Uri(self::_url()); foreach ($_FILES as $filename => $file) { $fileObject = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']); $request->_files[$filename] = $fileObject; } $request->header(getallheaders()); return $request; }