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, Функциональность сброса пароля
- Это не дубликат. Это похожая тема с другим подходом, который сработал хорошо.