You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make the dashboard work under host CSRF protection pipelines
When `FunWithFlags.UI.Router` is forwarded under a host pipeline that
already runs `Plug.CSRFProtection` — for example Phoenix's standard
`:browser` pipeline — the host registers a `before_send` callback that
raises `Plug.CSRFProtection.InvalidCrossOriginRequestError` whenever a
non-XHR GET returns a JavaScript response. The dashboard serves its own
`/assets/details.js` exactly that way, so the asset is rejected and the
UI fails to load.
The router now opts its own static asset GET/HEAD requests out of CSRF
protection by setting the documented `:plug_skip_csrf_protection` flag
before the asset is sent. `Plug.CSRFProtection` reads that flag at send
time, so it correctly suppresses the cross-origin check even though the
host registered its callback first. State-changing requests are never
skipped and remain fully CSRF-protected.
This means the dashboard works under the standard `:browser` pipeline
with no special pipeline and no host-side configuration. The previously
documented `:mounted_apps` recipe (which omitted `:protect_from_forgery`)
is no longer necessary.
Fixes#52.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,7 @@
2
2
3
3
## v1.2.0 (unreleased)
4
4
5
+
*`FunWithFlags.UI.Router` now works under Phoenix's standard `:browser` pipeline (or any host pipeline that uses `Plug.CSRFProtection`) without extra configuration. The router opts its own static asset `GET`/`HEAD` requests out of the host's CSRF protection, so the dashboard's cross-origin `<script>` and `<link>` requests no longer raise `Plug.CSRFProtection.InvalidCrossOriginRequestError`. State-changing requests remain fully CSRF-protected, and the previously documented `:mounted_apps` pipeline (one that omits `:protect_from_forgery`) is no longer necessary. ([issue/52](https://github.com/tompave/fun_with_flags_ui/issues/52))
5
6
* Drop support for Erlang/OTP 25, and Erlang/OTP >= 26 is now required. Dropping support for older versions of Erlang/OTP simply means that this package is not tested with them in CI, and that no compatibility issues are considered bugs.
Copy file name to clipboardExpand all lines: README.md
+12-16Lines changed: 12 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,25 +16,22 @@ It's primarily meant to be embedded in a host Plug application, either Phoenix o
16
16
17
17
### Mounted in Phoenix
18
18
19
-
The router plug can be mounted inside the Phoenix router with [`Phoenix.Router.forward/4`](https://hexdocs.pm/phoenix/Phoenix.Router.html#forward/4).
19
+
The router plug can be mounted inside the Phoenix router with [`Phoenix.Router.forward/4`](https://hexdocs.pm/phoenix/Phoenix.Router.html#forward/4). It works under Phoenix's standard `:browser` pipeline, so you can reuse the same pipeline that already handles sessions, secure headers, and authentication:
Note: There is no need to add `:protect_from_forgery` to the `:mounted_apps` pipeline because this package already implements CSRF protection. In order to enable it, your host application must use the `Plug.Session` plug, which is usually configured in the endpoint module in Phoenix.
32
+
The dashboard serves its own JavaScript and CSS from `/assets/*`. Because browsers request those `<script>` and `<link>` tags cross-origin, a host CSRF plug such as Phoenix's `:protect_from_forgery` would otherwise reject them with `Plug.CSRFProtection.InvalidCrossOriginRequestError`. `FunWithFlags.UI.Router` handles this for you: it opts its own asset `GET`/`HEAD` requests out of CSRF protection, while every state-changing request (creating, toggling, and deleting flags) stays fully CSRF-protected. No special pipeline and no extra configuration are required.
33
+
34
+
CSRF protection for those state-changing requests requires your host application to use the `Plug.Session` plug, which Phoenix configures in the endpoint module by default.
38
35
39
36
### Mounted in another Plug application
40
37
@@ -47,7 +44,7 @@ defmodule Another.App do
47
44
end
48
45
```
49
46
50
-
Note: If your plug router uses `Plug.CSRFProtection`, `FunWithFlags.UI.Router` should be added before your CSRF protection plug because it already implements its own CSRF protection. If you declare `FunWithFlags.UI.Router` after, your CSRF plug will likely block GET requests for the JS assets of the dashboard.
47
+
The same asset handling described above applies here: the router opts its own asset requests out of CSRF protection, so it works regardless of where your host application's `Plug.CSRFProtection` sits in the pipeline.
51
48
52
49
### Standalone
53
50
@@ -84,14 +81,13 @@ defmodule MyPhoenixAppWeb.Router do
0 commit comments