I
I
Ivan Privedenets2019-08-03 15:28:39
Django
Ivan Privedenets, 2019-08-03 15:28:39

How to solve csrf_token problem?

There is a page A on which the user specifies his mail to change the password. A message with a link to page B is sent to the mail. On page B, he updates his password and transfers it to the user's page using redirect.
When a user navigates to the page A tab from which the message was sent to the mail and updates it by resubmitting the form, the error "Forbidden (403)
CSRF verification failed. Request aborted."
How can csrf be updated? or how can I update page A itself after authorization? or is there another way to fix this problem?
Settings.py

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                # 'django.template.context_processors',
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'Performer.context_processors.context_processor',
            ],
        },
    },
]

View.py - page A from which the user sends a message to his mail.
class ForgotPassword(View):
    def get(self, request):

        form = EmailForm()

        return render(request, 'Performer/Forgot_password.html', context={'form': form})

    def post(self, request):

        form = EmailForm(request.POST)

        if request.method == 'POST' and form.is_valid():
            email = request.POST.get('email')
            try:
                user = User.objects.get(email=email)
            except ObjectDoesNotExist:
                message = 'Неверный Email'
                return render(request, 'Performer/Forgot_password.html', context={'form': form, 'message': message})

            signer = Signer()

            global script_email

            script_email = signer.sign(email)

            link = 'http://127.0.0.1:8000/change_password/' + script_email.split(':')[1] + '/'

            subject = 'Изменение пароля'

            html_message = render_to_string(
                'Performer/Password_message.html', {'link': link}
            )

            send_mail(subject, 'message', settings.EMAIL_HOST_USER, [email], html_message=html_message, fail_silently=False)

            message = 'Сообщение отправлено'

            return render(request, 'Performer/Forgot_password.html', context={'form': form, 'message': message})

Forgot_pass.html - Page A from which the user sends a message to his mail.
{% extends 'base.html' %}

{% block content %}
    <div class="forgot-pass-wrapper">
        <div class="forgot-pass-content">
            {% if message %}
                <div class="alert alert-info">{{ message }}</div>
            {% else %}
                <form class="forgot-pass-form" method="POST">{% csrf_token %}
                    
                    {{ form.as_p }}

                    <button class="btn btn-primary">Изменить пароль</button>
                </form>
            {% endif %}
        </div>
    </div>
{% endblock %}

View.py - Page In which the user changes his password.
class ChangePassword(View):
    def get(self, request, link):

        signer = Signer()

        global email

        email = signer.unsign(script_email)

        audit = signer.sign(email).split(':')[1]

        if link != audit:
            message = 'Паге нот фаунд'

            form = EmailForm()

            return render(request, 'Performer/Forgot_password.html', context={'form': form, 'message': message})

        form = ChangePasswordForm()

        return render(request, 'Performer/Change_password.html', context={'form': form})

    def post(self, request, link):

        form = ChangePasswordForm(request.POST)

        if request.method == 'POST' and form.is_valid():

            user = User.objects.get(email=email)

            new_password = form.cleaned_data['password_2']

            user.set_password(new_password)

            user.save()

            user = authenticate(request, username=user.username, password=new_password)

            login(request, user)

            return redirect('/user_profile/')

Change_password.html - Page B
{% extends 'base.html' %}

{% block content %}
    <div class="forgot-pass-wrapper">
        <div class="forgot-pass-content">
            <form class="change-pass-form" method="POST">{% csrf_token %}

                {{ form.as_p }}

                <button class="btn btn-primary">Изменить пароль</button>
            </form>
        </div>
        
    </div>
{% endblock %}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Guest007, 2019-08-03
@Ivan-Proger

Если страница А это форма с запросом на сброс (смену) пароля через емайл, то зачем возвращаться на эту страницу после установки нового пароля? Это нелогично.
А так - не вижу проблемы. На крайний случай - перегрузи (обнови) страницу (по F5 или снова открыв её по URLу) чтобы она снова по GET отдалась.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question