我正在使用Django 2.0.10,结合rest framework、rest-auth和allauth,以及React前端。Rest-auth提供了使用JWT令牌认证的登录和注销功能,但我不知道如何允许用户请求重新发送验证电子邮件。
我希望用户能够登录并点击一个按钮,显示“重新发送确认电子邮件”。例如,如果他们意外删除了电子邮件,则需要能够请求另一个电子邮件。
我看到一些帖子建议可以使用allauth中的send_email_confirmation,但这需要一个CSRF令牌,而该令牌将由模板生成。我尝试按照文档中免除csrf的方法,但没有任何区别。我还尝试设置authentication_classes = () 如此建议的。以下是我的代码:
settings:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
}
urls.py
from users.views import EmailConfirmation
urlpatterns = [
...
url(r'^/sendconfirmationemail/', EmailConfirmation.as_view(), name='send-email-confirmation')
]
views.py
from rest_framework.views import APIView
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
class EmailConfirmation(APIView):
@method_decorator(csrf_exempt)
authentication_classes = ()
def post(self):
send_email_confirmation(user=self.request.user)
当我向端点'/api/v1/rest-auth/sendconfirmationemail/'发布内容时,出现错误Forbidden。
<p>You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.</p>
<p>If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for 'same-origin' requests.</p>
编辑:我也尝试过像这样的教程中添加CSRF令牌到我的请求。但是我遇到了同样的问题。我尝试过以下方法:
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
//var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
然后我使用 Fetch API 构建请求,代码如下:
curl 'http://localhost:3000/api/v1/rest-auth/sendconfirmationemail/' -H 'Authorization: Token 55c8da5de68b657cf9dafd820a7f02f997fa3d64' -H 'Origin: http://localhost:3000' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-GB,en-US;q=0.9,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36' -H 'Content-Type: text/plain;charset=UTF-8' -H 'Accept: */*' -H 'Referer: http://localhost:3000/account' -H 'Connection: keep-alive' -H 'X-CSRFToken: YOHB6RXqpZMFIXKT31T9tAjaUsH0w3eIjaaCvbgAqmP64SWeVNd3Sz3g8nZUEmVS' --data-binary 'csrfmiddlewaretoken=YOHB6RXqpZMFIXKT31T9tAjaUsH0w3eIjaaCvbgAqmP64SWeVNd3Sz3g8nZUEmVS' --compressed
当我查看Django模板的工作示例时,我发现与表单数据一起发送的csrfmiddlewaretoken值与标头中发送的X-CSRFToken不同,我认为Django模板提供的值是盐值,并且这可能会产生差异。但是我找不到任何指示告诉我如何获取正确的值?或者我的fetch请求形式有误吗?
如果我在我的React页面中使用此表单:
<form action="api/v1/sendconfirmationemail" method="post">
<Input type="hidden" name="csrfmiddlewaretoken" value={this.getCookie('csrftoken')} />
<button type="submit">Send</button>
</form>
当我提交时,出现错误“方法不允许(POST):/ api / v1 / sendconfirmationemail”。来自此请求的cURL是:
curl 'http://localhost:3000/api/v1/sendconfirmationemail' -H 'Cookie: csrftoken=YOHB6RXqpZMFIXKT31T9tAjaUsH0w3eIjaaCvbgAqmP64SWeVNd3Sz3g8nZUEmVS; sessionid=uslpdgd5npa6wyk2oqpwkhj79xaen7nw' -H 'Origin: http://localhost:3000' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-GB,en-US;q=0.9,en;q=0.8' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8' -H 'Cache-Control: max-age=0' -H 'Referer: http://localhost:3000/account' -H 'Connection: keep-alive' --data 'csrfmiddlewaretoken=YOHB6RXqpZMFIXKT31T9tAjaUsH0w3eIjaaCvbgAqmP64SWeVNd3Sz3g8nZUEmVS' --compressed
我该如何在React前端请求重新发送电子邮件?