Django Vue.js PasswordResetView, размещенный с помощью Axios, получает ошибку 403 Forbidden CSRF Token

Я пытаюсь создать пользовательскую страницу восстановления электронной почты во фронтенде с помощью Vue.js. Там я пытаюсь отправить входные данные с электронной почтой с помощью Axios через /api/v1/accounts/password_reset/, так что в основном я пытаюсь использовать оригинальный ResetPasswordView и вместо того, чтобы использовать его шаблон, я использую его в качестве конечной точки. Когда я отправляю значение, консоль возвращает ошибку 403 Forbidden CSRF Token, как показано ниже. Что можно сделать, чтобы избежать этого?

Forbidden (CSRF cookie not set.): /api/v1/accounts/password_reset/
[07/Sep/2021 16:32:55] "POST /api/v1/accounts/password_reset/ HTTP/1.1" 403 2864
/Users/IvanStepanchuk/Desktop/web-project/web-backend/core/settings.py changed, reloading.
Watching for file changes with StatReloader
Performing system checks...

Это мой ResetPassword.vue:

<template>
    <div id="login">
        <div class="w-100 d-flex justify-content-center" id="home__screen">
            <div class="col-sm col-lg-4 text-center align-self-center decorator__spacing">
                <div class="card bg-white p-4">
                    <h1 class="fs-3 pb-3">Recover your account</h1>
                    <form @submit.prevent="passwordReset">
                        <div class="mb-3">
                            <input type="email" class="form-control" id="username" v-model="email" aria-describedby="emailHelp" placeholder="Email con el cual se ha registrado">
                        </div>
                        <div class="alert alert-primary d-flex flex-column" role="alert" v-if="errors.length">
                            <span v-for="error in errors" v-bind:key="error">{{error}}</span>
                        </div>
                        <button type="submit" class="btn btn-primary mb-3">Enviar</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'ResetPassword',
  data() {
      return {
          email: '',
          errors: []
      }
  },
  components: {
    
  },
  mounted() {
      document.title = 'Company | Recover Account'
  },
  methods: {
        passwordReset() {
            this.errors = []
            if (this.email === '') {
                this.errors.push('Email field is empty')
            }

            const passwordResetForm = {
                email: this.email
            }
            axios
                .post("/api/v1/accounts/password_reset/", passwordResetForm)
                .then(response => {
                    this.$router.push('/login')
                    return response
                })
                .catch(error => {
                    this.errors.push('Something is not working well')
                    console.log(error)
                })
        }

  }
}
</script>

<style scoped>

</style>

Или как лучше всего использовать пользовательские представления Vue.js для управления функциональностью сброса пароля (чтобы не использовать шаблоны Django)? Спасибо!

Проблема в том, что в вашем passwordResetForm нет csrf_token. Это просто объект с email в нем. Django не позволяет этого по умолчанию из соображений безопасности. (подробнее см.: документация о CSRF)

Вы можете получить токен csrf со страницы с помощью следующего кода:

function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            // 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;
}
const csrftoken = getCookie('csrftoken');

А затем передайте csrftoken в заголовках ваших ajax.post()

Я смог решить эту проблему, создав пользовательские методы и классы Views.py, вы можете увидеть решение здесь: Django Rest Framework + Serializers + Vue.js, Функциональность сброса пароля

  • Это не дубликат. Это похожая тема с другим подходом, который сработал хорошо.
Вернуться на верх