简体   繁体   English

如何使用 allauth 和 rest-auth 从 React 前端在 Django 中重新发送确认电子邮件

[英]How to resend confirmation email in Django from a React front end, using allauth and rest-auth

I'm using Django 2.0.10 with rest framework, rest-auth and allauth, with a React front end.我将 Django 2.0.10 与 rest 框架、rest-auth 和 allauth 一起使用,并带有 React 前端。 Rest-auth provides login and logout functionality using JWT token authentication, but I can't work out how to allow the user to request a resend of the verification email. Rest-auth 使用 JWT 令牌身份验证提供登录和注销功能,但我无法弄清楚如何允许用户请求重新发送验证电子邮件。

I want a user to be able to log in and press a button saying "Resend confirmation email".我希望用户能够登录并按下“重新发送确认电子邮件”按钮。 If for example they accidentally deleted the email, they need to be able to request another.例如,如果他们不小心删除了电子邮件,他们需要能够请求另一个。

I've seen posts suggesting that you can use send_email_confirmation from allauth, but this expects a CSRF token which would be generated by a template.我已经看到帖子建议您可以使用 allauth 的 send_email_confirmation,但这需要一个由模板生成的 CSRF 令牌。 I tried following the docs to excempt from csrf, but it doesn't make any different.我尝试按照文档从 csrf 中排除,但它没有任何不同。 I also tried setting authentication_classes = () as suggested here .我还尝试按照此处的建议设置 authentication_classes = () 。 Here's my code:这是我的代码:

settings:设置:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
}

urls.py网址.py

from users.views import EmailConfirmation

urlpatterns = [
...
url(r'^/sendconfirmationemail/', EmailConfirmation.as_view(), name='send-email-confirmation')
]

views.py视图.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)

When I post to the endpoint '/api/v1/rest-auth/sendconfirmationemail/', I get an error Forbidden:当我发布到端点“/api/v1/rest-auth/sendconfirmationemail/”时,我收到错误禁止:

<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 &#39;same-origin&#39; requests.</p>

Edit: I have also tried to add the CSRF token to my request following tutorials like this one .编辑:我也试图在CSRF令牌添加到我的请求以下教程像这样的 But I have the same problem.但我有同样的问题。 Here's what I've tried:这是我尝试过的:

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;
}

And then I construct my request to use fetch API like this:然后我构造我的请求以使用 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

When I look at working examples from Django templates, I see that the csrfmiddlewaretoken value sent with the form data is not the same as the X-CSRFToken sent in the header - I think the value supplied by Django templates is salted and this might make a difference.当我查看来自 Django 模板的工作示例时,我发现随表单数据发送的 csrfmiddlewaretoken 值与在标头中发送的 X-CSRFToken 不同 - 我认为 Django 模板提供的值是加盐的,这可能会导致区别。 But no instructions I can find tell me how to get the right value?但是我找不到任何说明告诉我如何获得正确的价值? Or do I have my fetch request in the wrong form somehow?或者我以某种方式以错误的形式收到了我的提取请求?

If I use this form in my React page:如果我在 React 页面中使用此表单:

<form action="api/v1/sendconfirmationemail" method="post">
<Input type="hidden" name="csrfmiddlewaretoken"  value={this.getCookie('csrftoken')} />
<button type="submit">Send</button>
</form>

When I submit it, I get an error "Method Not Allowed (POST): /api/v1/sendconfirmationemail".当我提交它时,我收到错误“不允许的方法(POST):/api/v1/sendconfirmationemail”。 The cURL from this request is:此请求的 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

Any idea how I can request an email resend from the React frontend?知道如何从 React 前端请求重新发送电子邮件吗?

I think part of my trouble was that the server seems to show the Forbidden (CSRF cookie not set.) error if the fetch request has the incorrect URL and is therefore not pointing at a valid rest-framework URL.我认为我的部分问题是,如果获取请求的 URL 不正确,服务器似乎会显示Forbidden (CSRF cookie not set.) error ,因此没有指向有效的 rest-framework URL。 This had me chasing after CSRF issues instead of double checking my URL.这让我追逐 CSRF 问题,而不是仔细检查我的 URL。

I hope this will help somebody else.我希望这会帮助别人。 Here's my working code:这是我的工作代码:

users/views.py用户/视图.py

from allauth.account.signals import email_confirmed
from django.dispatch import receiver
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated

from allauth.account.utils import send_email_confirmation
from rest_framework.views import APIView

from . import models
from . import serializers

from rest_framework.authentication import TokenAuthentication
from rest_framework import status
from rest_framework.response import Response

class UserListView(generics.ListCreateAPIView):
    queryset = models.CustomUser.objects.all()
    serializer_class = serializers.UserSerializer
    authentication_classes = (TokenAuthentication,)

# when the email is confirmed, set a field on the user
# so the UI can check whether to show the "Resend confirmation email" button
@receiver(email_confirmed)
def email_confirmed_(request, email_address, **kwargs):
    user = email_address.user
    user.email_verified = True

    user.save()

# request a new confirmation email
class EmailConfirmation(APIView):
    permission_classes = [IsAuthenticated] 

    def post(self, request):
        if request.user.email_verified:
            return Response({'message': 'Email already verified'}, status=status.HTTP_201_CREATED)

        send_email_confirmation(request, request.user)
        return Response({'message': 'Email confirmation sent'}, status=status.HTTP_201_CREATED)

api/urls.py api/urls.py

from users.views import EmailConfirmation

urlpatterns = [
...
    path('sendconfirmationemail/', EmailConfirmation.as_view(), name='send-email-confirmation')
]

I'm sending a POST request using JavaScript fetch(), with the authentication token in the header like this:我正在使用 JavaScript fetch() 发送 POST 请求,标头中带有身份验证令牌,如下所示:

-H 'Authorization: Token 98254e6004e4a28b9d8cf61e7a7a9ee2fc61009a' 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 django rest-auth带有邮戳的电子邮件确认 - django rest-auth email confirmation with postmark 如何判断用户的电子邮件地址是否已使用 Django、allauth、rest-auth 和自定义用户进行验证 - How to tell if user's email address has been verified using Django, allauth, rest-auth and a custom user Django rest-auth / allauth和微博集成 - Django rest-auth/allauth and weibo integration 使用rest-auth从Django all-auth检索给定确认密钥(电子邮件验证)的用户电子邮件地址 - Retrieve user e-mailaddress given confirmation key (email verification) from Django all-auth with rest-auth Django rest-auth allauth 注册 email,名字和姓氏,没有用户名 - Django rest-auth allauth registration with email, first and last name, and without username Apple 使用 allauth 和 rest-auth 在 django rest 框架中登录 - Apple login in django rest framework with allauth and rest-auth 在 django allauth 中解决未授权 /rest-auth/registration/ 错误 - solving error unauthorized /rest-auth/registration/ in django allauth django rest-auth /注册电子邮件验证 - django rest-auth/registration email validation Django+React 休息认证 - Django+React rest-auth Django REST 身份验证:电子邮件确认后呈现 django-allauth 模板时出错 - Django REST auth: error rendering django-allauth template after email confirmation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM