3 namespace Drupal\Core\Access;
5 use Drupal\Core\Routing\Access\AccessInterface as RoutingAccessInterface;
6 use Drupal\Core\Routing\RouteMatchInterface;
7 use Symfony\Component\Routing\Route;
8 use Symfony\Component\HttpFoundation\Request;
11 * Allows access to routes to be controlled by a '_csrf_token' parameter.
13 * To use this check, add a "token" GET parameter to URLs of which the value is
14 * a token generated by \Drupal::csrfToken()->get() using the same value as the
15 * "_csrf_token" parameter in the route.
17 class CsrfAccessCheck implements RoutingAccessInterface {
20 * The CSRF token generator.
22 * @var \Drupal\Core\Access\CsrfTokenGenerator
27 * Constructs a CsrfAccessCheck object.
29 * @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token
30 * The CSRF token generator.
32 public function __construct(CsrfTokenGenerator $csrf_token) {
33 $this->csrfToken = $csrf_token;
37 * Checks access based on a CSRF token for the request.
39 * @param \Symfony\Component\Routing\Route $route
40 * The route to check against.
41 * @param \Symfony\Component\HttpFoundation\Request $request
43 * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
44 * The route match object.
46 * @return \Drupal\Core\Access\AccessResultInterface
49 public function access(Route $route, Request $request, RouteMatchInterface $route_match) {
50 $parameters = $route_match->getRawParameters();
51 $path = ltrim($route->getPath(), '/');
52 // Replace the path parameters with values from the parameters array.
53 foreach ($parameters as $param => $value) {
54 $path = str_replace("{{$param}}", $value, $path);
57 if ($this->csrfToken->validate($request->query->get('token', ''), $path)) {
58 $result = AccessResult::allowed();
61 $result = AccessResult::forbidden($request->query->has('token') ? "'csrf_token' URL query argument is invalid." : "'csrf_token' URL query argument is missing.");
63 // Not cacheable because the CSRF token is highly dynamic.
64 return $result->setCacheMaxAge(0);