Skip to content

Commit 2ef77b1

Browse files
authored
Use POST method instead of GET to perform logout in browsable API (#9208)
* Use POST method instead of GET to perform logout in browsable API * Add a test that checks the presence of the logout form
1 parent df89f32 commit 2ef77b1

File tree

4 files changed

+17
-6
lines changed

4 files changed

+17
-6
lines changed

rest_framework/templates/rest_framework/admin.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<ul class="nav navbar-nav pull-right">
4343
{% block userlinks %}
4444
{% if user.is_authenticated %}
45-
{% optional_logout request user %}
45+
{% optional_logout request user csrf_token %}
4646
{% else %}
4747
{% optional_login request %}
4848
{% endif %}

rest_framework/templates/rest_framework/base.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
<ul class="nav navbar-nav pull-right">
4747
{% block userlinks %}
4848
{% if user.is_authenticated %}
49-
{% optional_logout request user %}
49+
{% optional_logout request user csrf_token %}
5050
{% else %}
5151
{% optional_login request %}
5252
{% endif %}

rest_framework/templatetags/rest_framework.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def optional_docs_login(request):
119119

120120

121121
@register.simple_tag
122-
def optional_logout(request, user):
122+
def optional_logout(request, user, csrf_token):
123123
"""
124124
Include a logout snippet if REST framework's logout view is in the URLconf.
125125
"""
@@ -135,11 +135,16 @@ def optional_logout(request, user):
135135
<b class="caret"></b>
136136
</a>
137137
<ul class="dropdown-menu">
138-
<li><a href='{href}?next={next}'>Log out</a></li>
138+
<form id="logoutForm" method="post" action="{href}?next={next}">
139+
<input type="hidden" name="csrfmiddlewaretoken" value="{csrf_token}">
140+
</form>
141+
<li>
142+
<a href="#" onclick='document.getElementById("logoutForm").submit()'>Log out</a>
143+
</li>
139144
</ul>
140145
</li>"""
141-
snippet = format_html(snippet, user=escape(user), href=logout_url, next=escape(request.path))
142-
146+
snippet = format_html(snippet, user=escape(user), href=logout_url,
147+
next=escape(request.path), csrf_token=csrf_token)
143148
return mark_safe(snippet)
144149

145150

tests/browsable_api/test_browsable_api.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ def test_login_shown_when_logged_out(self):
6565
content = response.content.decode()
6666
assert '>Log in<' in content
6767

68+
def test_dropdown_contains_logout_form(self):
69+
self.client.login(username=self.username, password=self.password)
70+
response = self.client.get('/')
71+
content = response.content.decode()
72+
assert '<form id="logoutForm" method="post" action="/auth/logout/?next=/">' in content
73+
6874

6975
@override_settings(ROOT_URLCONF='tests.browsable_api.no_auth_urls')
7076
class NoDropdownWithoutAuthTests(TestCase):

0 commit comments

Comments
 (0)