|
17 | 17 | use CraftCms\Cms\Cp\Html\ElementHtml; |
18 | 18 | use CraftCms\Cms\ProjectConfig\ProjectConfig; |
19 | 19 | use CraftCms\Cms\User\Elements\User; |
| 20 | +use Illuminate\Foundation\Http\Middleware\PreventRequestForgery; |
20 | 21 | use Illuminate\Support\Facades\Auth; |
21 | 22 | use Illuminate\Support\Facades\Gate; |
22 | 23 | use InvalidArgumentException; |
@@ -58,6 +59,17 @@ abstract class Controller extends \yii\web\Controller |
58 | 59 | public const ALLOW_ANONYMOUS_LIVE = 1; |
59 | 60 | public const ALLOW_ANONYMOUS_OFFLINE = 2; |
60 | 61 |
|
| 62 | + public $enableCsrfValidation = true { |
| 63 | + get => $this->enableCsrfValidation; |
| 64 | + set($value) { |
| 65 | + $this->enableCsrfValidation = (bool) $value; |
| 66 | + |
| 67 | + if (!$this->enableCsrfValidation) { |
| 68 | + $this->registerCsrfValidationExclusion(); |
| 69 | + } |
| 70 | + } |
| 71 | + } |
| 72 | + |
61 | 73 | /** |
62 | 74 | * @var int|bool|int[]|string[] Whether this controller’s actions can be accessed anonymously. |
63 | 75 | * |
@@ -139,6 +151,41 @@ public function init(): void |
139 | 151 | } |
140 | 152 |
|
141 | 153 | parent::init(); |
| 154 | + |
| 155 | + if (!$this->enableCsrfValidation) { |
| 156 | + $this->registerCsrfValidationExclusion(); |
| 157 | + } |
| 158 | + } |
| 159 | + |
| 160 | + public function registerCsrfValidationExclusion(): void |
| 161 | + { |
| 162 | + if (!isset($this->id, $this->module)) { |
| 163 | + return; |
| 164 | + } |
| 165 | + |
| 166 | + PreventRequestForgery::except($this->csrfValidationExclusionUris()); |
| 167 | + } |
| 168 | + |
| 169 | + private function csrfValidationExclusionUris(): array |
| 170 | + { |
| 171 | + $route = trim($this->getUniqueId(), '/'); |
| 172 | + |
| 173 | + if ($route === '') { |
| 174 | + return []; |
| 175 | + } |
| 176 | + |
| 177 | + $actionTrigger = trim(Cms::config()->actionTrigger, '/'); |
| 178 | + $cpTrigger = trim(Cms::config()->cpTrigger, '/'); |
| 179 | + |
| 180 | + return collect([ |
| 181 | + $route, |
| 182 | + implode('/', array_filter([$actionTrigger, $route], fn(string $segment) => $segment !== '')), |
| 183 | + implode('/', array_filter([$cpTrigger, $actionTrigger, $route], fn(string $segment) => $segment !== '')), |
| 184 | + ]) |
| 185 | + ->flatMap(fn(string $route) => [$route, "$route/*"]) |
| 186 | + ->unique() |
| 187 | + ->values() |
| 188 | + ->all(); |
142 | 189 | } |
143 | 190 |
|
144 | 191 | /** |
|
0 commit comments