<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>

CC BY-SA 4.0
2022-04-12T15:28:15.363Z
Thanks for your answer. That's exactly it !
Sylvain Tremblay
CC BY-SA 4.0
2022-04-04T21:37:50.440Z
2022-04-04T21:37:50.440Z
August Miller
<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>

CC BY-SA 4.0
2022-12-20T00:21:52.100Z
2022-12-20T00:21:52.100Z
odlh
<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>

CC BY-SA 4.0
2022-04-04T20:45:26.517Z
Another way of asking this (if I understand correctly) might be "How can I POST to a CSRF-protected action without a session?"
August Miller
<csrf><post>
CSRF token using Craft as an API
# 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, or for requests where a token needs to be created on-the-fly, 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…
class AppHookController extends Controller
{
    public $enableCsrfValidation = false;

    // ...

    public function actionReceiveData()
    {
        // Your processing logic!
    }
}

…or even for a single action…
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:
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 August posted and created a tutorial that I hope helps others create APIs with Craft.

<https://delasign.com/blog/craft-cms-api/>


---

