cms icon indicating copy to clipboard operation
cms copied to clipboard

[6.x] Decouple CSRF token from nocache script

Open aerni opened this issue 1 year ago • 1 comments

What it does

This PR takes another stab at https://github.com/statamic/cms/pull/10306 which was reverted in https://github.com/statamic/cms/pull/10898. The nocache_js_position config option introduced in the latter PR isn't optimal, as you've got to pick your poison and choose between Livewire or nocache to work as expected.

This PR picks up on the idea pointed out here and extracts the CSRF token replacer script from the nocache replacer script. The CSRF replacer script is inserted as the first script in the head, while the nocache replacer script is placed at the end of the body. This way, you don't have to pick the script's position and can have both Livewire and nocache work alongside each other.

Note

This PR has undergone several iterations. Previously, I put the decoupling of the scripts behind a feature flag. This wasn't optimal but allowed for a non-breaking update. With the release of Statamic 6 coming close, I figured I might as well make this a breaking change.

Breaking changes

Events

The statamic:nocache.replaced event is no longer dispatched when the CSRF token is replaced. It is now only dispatched by the nocache script. Instead, you should use the new statamic:csrf.replaced event.

Script replacement

The StaticCache::nocacheJs($script) method now only replaces the nocache script. It doesn't touch the CSRF token script. Use the new StaticCache::csrfTokenJs($script) method if you want to customize the CSRF script.

Removed config option

The nocache_js_position config option introduced in https://github.com/statamic/cms/pull/10898 is obsolete now and has been removed.

Testing

Here's a basic layout that you can use for testing. Note, that the CSRF token is replaced and nocache also works. Make sure to enable the new config option and full static caching.

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
        {{ nocache }}
            {{ now | iso_format('Y-m-d H:i:s') }}
        {{ /nocache }}
        <script data-csrf="{{ csrf_token }}"></script>
    </body>
</html>

aerni avatar Oct 25 '24 21:10 aerni