Answers.Body: <p>There are a few answers about controlling CSRF protection on a <a href="https://craftcms.stackexchange.com/questions/4553/whats-the-best-way-to-skip-csrf-for-plugin-controllers?rq=1">per-endpoint basis</a>, or for requests where a token needs to be <a href="https://craftcms.stackexchange.com/questions/28735/csrf-in-headless-applications">created on-the-fly</a>, but I think your question is unique.</p>
  <p>It sounds like your client's internal application will be issuing a “stateless” request (i.e. without a session), sort of like a webhook. I'd also be willing to be that they can't or won't provide support for a custom handler capable of emulating a session—something that would require at least two discrete requests; one to start the session and get a token, and a second to submit it and the payload.</p>
  <p>If you have a custom Controller receiving the data, you can tell it to ignore CSRF, without disabling it for the entire app…</p>
  <pre class="lang-php prettyprint-override"><code>class AppHookController extends Controller
  {
      public $enableCsrfValidation = false;
  
      // ...
  
      public function actionReceiveData()
      {
          // Your processing logic!
      }
  }
  </code></pre>
  <p>…or even for a single action…</p>
  <pre class="lang-php prettyprint-override"><code>class AppHookController extends Controller
  {
      // ...
  
      public function beforeAction($action): bool
      {
          // Disable protection for only one action:
          if ($action-&gt;id === 'receive-data') {
              $this-&gt;enableCsrfProtection = false;
          }
  
          return parent::beforeAction($action);
      }
  
      public function actionReceiveData()
      {
          // Your processing logic!
      }
  }
  </code></pre>
  <p> Either of these could be combined with a kind of &quot;shared secret&quot; between your site and the internal application that can be checked during the request.</p>
  <p>If you are piggybacking on a built-in Craft controller, you can be notified when it is about to process a request:</p>
  <pre class="lang-php prettyprint-override"><code>Event::on(
      EntriesController::class,
      EntriesController::EVENT_BEFORE_ACTION,
      function (ActionEvent $e) {
          $action = $e-&gt;action;
          $controller = $action-&gt;controller;
  
          if ($e-&gt;action-&gt;id === 'receive-data') {
              $controller-&gt;enableCsrfProtection = false;
          }
      });
  </code></pre>
  <p>☠️ I would strongly advise <em>not</em> deploying this solution, as misconfiguration can <em>significantly</em> impact the security of your application!</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-12T15:28:15.363Z
Answers.Text: Thanks for your answer. That's exactly it !
Answers.UserDisplayName: Sylvain Tremblay
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-04T21:37:50.440Z
Answers.LastActivityDate: 2022-04-04T21:37:50.440Z
Answers.UserDisplayName: August Miller
Answers.Body: <p>I managed to solve it using the answer August posted and created a tutorial that I hope helps others create APIs with Craft.</p>
  <p><a href="https://delasign.com/blog/craft-cms-api/" rel="nofollow noreferrer">https://delasign.com/blog/craft-cms-api/</a></p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-20T00:21:52.100Z
Answers.LastActivityDate: 2022-12-20T00:21:52.100Z
Answers.UserDisplayName: odlh
Body: <p>Our Craft site needs to exchange data with our customer in-house APP. And at some point it needs for the APP to POST us updates.
  We set some sort of API with a Api and Secret Key to exchange between platform. Everything works fine on DEV as we turned off the <code>enableCsrfProtection</code>. But sure enough won't work and obviously we need to keep it on for all the rest of the pages for security reason.</p>
  <p>So my question is : How can the APP post us data with this security ON ? I mean it's not like we put a form with the value or anything like this. I'm puzzled. Sure enough I research and saw this page: <a href="https://craftcms.com/knowledge-base/enabling-csrf-protection#updating-your-javascript" rel="nofollow noreferrer">https://craftcms.com/knowledge-base/enabling-csrf-protection#updating-your-javascript</a> but I don't see the solution it this... Maybe it's just me ! :D</p>
  <p>Thanks for your input.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-04-04T20:45:26.517Z
Comments.Text: Another way of asking this (if I understand correctly) might be "How can I POST to a CSRF-protected action without a session?"
Comments.UserDisplayName: August Miller
Tags: <csrf><post>
Title: CSRF token using Craft as an API
ThreadText: # CSRF token using Craft as an API
  
  (Asked by: username_0 on 2022-04-04)
  
  Our Craft site needs to exchange data with our customer in-house APP. And at some point it needs for the APP to POST us updates.
  We set some sort of API with a Api and Secret Key to exchange between platform. Everything works fine on DEV as we turned off the `enableCsrfProtection`. But sure enough won't work and obviously we need to keep it on for all the rest of the pages for security reason.
  
  So my question is : How can the APP post us data with this security ON ? I mean it's not like we put a form with the value or anything like this. I'm puzzled. Sure enough I research and saw this page: <https://craftcms.com/knowledge-base/enabling-csrf-protection#updating-your-javascript> but I don't see the solution it this... Maybe it's just me ! :D
  
  Thanks for your input.
  
  **Tags:** csrf, post
  
  > **Comments:**
  > **username_1**: Another way of asking this (if I understand correctly) might be "How can I POST to a CSRF-protected action without a session?"  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2022-04-04. Score: 2 | Accepted answer
  
  There are a few answers about controlling CSRF protection on a [per-endpoint basis](https://craftcms.stackexchange.com/questions/4553/whats-the-best-way-to-skip-csrf-for-plugin-controllers?rq=1), or for requests where a token needs to be [created on-the-fly](https://craftcms.stackexchange.com/questions/28735/csrf-in-headless-applications), but I think your question is unique.
  
  It sounds like your client's internal application will be issuing a “stateless” request (i.e. without a session), sort of like a webhook. I'd also be willing to be that they can't or won't provide support for a custom handler capable of emulating a session—something that would require at least two discrete requests; one to start the session and get a token, and a second to submit it and the payload.
  
  If you have a custom Controller receiving the data, you can tell it to ignore CSRF, without disabling it for the entire app…
  
  ```php
  class AppHookController extends Controller
  {
      public $enableCsrfValidation = false;
  
      // ...
  
      public function actionReceiveData()
      {
          // Your processing logic!
      }
  }
  
  ```
  
  …or even for a single action…
  
  ```php
  class AppHookController extends Controller
  {
      // ...
  
      public function beforeAction($action): bool
      {
          // Disable protection for only one action:
          if ($action->id === 'receive-data') {
              $this->enableCsrfProtection = false;
          }
  
          return parent::beforeAction($action);
      }
  
      public function actionReceiveData()
      {
          // Your processing logic!
      }
  }
  
  ```
  
  Either of these could be combined with a kind of "shared secret" between your site and the internal application that can be checked during the request.
  
  If you are piggybacking on a built-in Craft controller, you can be notified when it is about to process a request:
  
  ```php
  Event::on(
      EntriesController::class,
      EntriesController::EVENT_BEFORE_ACTION,
      function (ActionEvent $e) {
          $action = $e->action;
          $controller = $action->controller;
  
          if ($e->action->id === 'receive-data') {
              $controller->enableCsrfProtection = false;
          }
      });
  
  ```
  
  ☠️ I would strongly advise *not* deploying this solution, as misconfiguration can *significantly* impact the security of your application!
  
  > **Comments:**
  > **username_0**: Thanks for your answer. That's exactly it !  
  
  ---
  
  ### Answer by username_2 on 2022-12-20. Score: 2
  
  I managed to solve it using the answer username_1 posted and created a tutorial that I hope helps others create APIs with Craft.
  
  <https://delasign.com/blog/craft-cms-api/>
  
  
  ---
  
  