limited-pillow-24427
12/31/2021, 11:30 AMcheck_username
view in accounts (template='accounts/register').
I got proper response (if I'm looking at Network in Dev Tools), see that something is changing in my #username-error div (hx-settling), but content doesnt appear :/user
12/31/2021, 11:52 AMuser
12/31/2021, 11:52 AMcool-camera-13454
12/31/2021, 1:52 PMmethod=post
and a <button>
with a type=submit
attribute. If you are going to use regular forms to POST the data, you could simply boost these forms with the hx-boost
attribute (https://htmx.org/attributes/hx-boost/), that could be enough to add the UX you are looking for. So something like this:
html
<div hx-boost="true">
<form method="post" action="some/url/endpoint" hx-push-url="true">
{% csrf_token %}
<button type="submit">Submit</button>
</form>
</div>
If you are POSTing from a diferent HTML element using hx-post
, you can do so too. But in that case you have to of course configure your backend so that it returns the exact HTML you want to swap in your frontend. The advantage of "boosted" forms is that HTMX figures out what to swap in your document.
I would say, if after POSTing your data, you want to go to a different route/url, use a boosted form. But if you want to stay in the same route/url, use any HTML element that makes sense (like a button or input for example) with an hx-post
attribute swapping a part of your documentcool-camera-13454
12/31/2021, 1:55 PMcool-camera-13454
12/31/2021, 1:56 PMwhite-motorcycle-95262
12/31/2021, 2:47 PM{{ csrf_token }}
would be static, and then after someone logs in and out, Django would expect a different token, but HTMX is not updating the part of the template with {{ csrf_token }}
cool-camera-13454
12/31/2021, 2:51 PMcool-camera-13454
12/31/2021, 3:33 PMcsrftoken
cookie on every user login (or if no cookie exists too, I suppose). When sending POST requests, Django's CSRF middleware expects a csrfmiddlewaretoken
as part of the POST request. This token is generated on each template generation, based on the csrftoken
Cookie, that's why this value changes on every page visit. This is the value you obtain using the {% csrf_token %}
template tag. That's why for regular forms, we add this tag inside the form, so that this token is included in the POST request parameters, which will then be checked by the Django's middleware, to see if the POST request is valid or not.
For POST requests triggered by htmx's hx-post
, we need a way to send this csrfmiddlewaretoken
information to the server. Instead of adding the parameter to every POST request (like with regular forms), the htmx approach uses a different solution provided by Django for AJAX calls: the X-CSRFToken
header. This is what is added with the event listener on the base template. According to Django's documentation, this alternative should do the same as using the {% csrf_token %}
template tag:
> While the above method can be used for AJAX POST requests, it has some inconveniences: you have to remember to pass the CSRF token in as POST data with every POST request. For this reason, there is an alternative method: on each XMLHttpRequest, set a custom X-CSRFToken header (as specified by the CSRF_HEADER_NAME setting) to the value of the CSRF token. This is often easier because many JavaScript frameworks provide hooks that allow headers to be set on every request.
To sum up, I think both regular form POST requests and htmx hx-post
requests have the same CSRF protection, they only get their tokens differentlywhite-motorcycle-95262
12/31/2021, 3:58 PM{% csrf_token %}
I think it will be the wrong one once you login/logout without a full page refresh. I think we would need to use the getCookie
JS function described here: https://docs.djangoproject.com/en/4.0/ref/csrf/ to get the CSRF token from the cookie, which is updated every request, unlike the template with the {% csrf_token %}
taglimited-pillow-24427
12/31/2021, 4:16 PMflat-flower-95472
12/31/2021, 5:17 PMwhite-motorcycle-95262
12/31/2021, 6:46 PMgetCookie
method from Django's documentation with the script in step 1 of https://www.mattlayman.com/blog/2021/how-to-htmx-django/hundreds-camera-24900
12/31/2021, 7:21 PM<script>
document.body.addEventListener('htmx:configRequest', (event) => {
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
})
</script>
and haven't had any issues so farhundreds-camera-24900
12/31/2021, 7:21 PMhundreds-camera-24900
12/31/2021, 7:21 PMhundreds-camera-24900
12/31/2021, 7:22 PMhundreds-camera-24900
12/31/2021, 7:25 PMcool-camera-13454
12/31/2021, 7:28 PM{% csrf_token %}
tags and an "htmx login/logout" with hx-post
. I've seen the following:
- Every time you login a new CSRF cookie is created when logging in, regardless if you use a regular form or the "htmx login"
- If using the "htmx login", the csrfmiddlewaretoken
generated by {% csrf_token %}
does not change, so the event listener will keep sending this same token until a regular HTTP request happens
I don't know if not refreshing this is a problem or not. Your proposed solution of using getCookie
seems a good approach to refresh it with every AJAX request.
I would say however, that most of the times, after login or logout, you would want to go to a different route/url (like dashboard, home or something like that). So I think that instead of using the "htmx login", it seems easier to use a regular boosted <form>
to trigger that reload of the body (but since it's boosted, you don't see the flash from a page refresh, which is cool)prehistoric-cat-63987
01/01/2022, 9:35 AMuser
01/01/2022, 2:05 PMuser
01/01/2022, 2:07 PMprehistoric-cat-63987
01/01/2022, 6:06 PMprehistoric-cat-63987
01/01/2022, 6:08 PMuser
01/01/2022, 7:52 PMhundreds-camera-24900
01/02/2022, 4:44 PMhundreds-camera-24900
01/02/2022, 4:46 PMcool-camera-13454
01/02/2022, 5:37 PMcool-camera-13454
01/02/2022, 5:39 PMhundreds-camera-24900
01/02/2022, 5:54 PM