我正在使用带有JWT(JSON Web令牌)身份验证的DRF。我想使用django的内置重置密码功能。所以,我已经包含了网址:
url('^', include('django.contrib.auth.urls')),
但是,当然,在API下,调用https://.../password_reset/
会导致csrf token missing
错误。我想知道我应该采取哪种方法来解决这个问题。我应该更改内置的reset_password
视图并删除csrf保护吗?创建一个接受email
(reset_password
视图post参数)的DRF端点是一个更好的主意,然后以某种方式生成一个csrf令牌并将其发送到redirect(reverse("reset_password"), email=email)
的视图...但是,redirect
不会向post
视图发送reset_password
请求。也许将电子邮件保存到session
?任何建议都会有所帮助。
答案 0 :(得分:3)
我认为在密码重置端点的情况下,可以安全地删除CSRF保护。 CSRF保护用于经过身份验证的端点,以防止其他网站使用用户存储的凭据来获取未经授权的访问。由于Django使用的PasswordResetForm除了发送电子邮件之外不会做任何其他事情,因此除了通过密码重置电子邮件向他们发送垃圾邮件之外,攻击者除了骚扰用户外,还能做很多事情。
你可以使用第三方,但如果您正在做的只是添加密码重置端点,那么您只需要几行代码。
views.py
import json
from django.contrib.auth.forms import PasswordResetForm
from django.http.response import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
@csrf_exempt
@require_http_methods(['POST'])
def email_password_reset(request):
# the POST body should be in the format {'email': 'user@user.com'}
try:
# you could also uncomment the following line if you wanted this view to be anonymous only
# assert not request.user.is_authenticated()
assert request.META.get('CONTENT_TYPE', '') == 'application/json'
body = json.loads(request.body)
except (AssertionError, TypeError):
pass
else:
form = PasswordResetForm(body)
if form.is_valid():
form.save()
finally:
return HttpResponse(status=200)
urls.py
urlpatterns = patterns(...
url(r'^/api/password_reset/$', 'email_password_reset', name='email-password-reset')
...)