Получение ошибки: Forbidden (CSRF cookie не установлен.) при попытке сделать пост-запрос к представлению Django
Я пытаюсь создать (расширение для хрома + Django) менеджер паролей, который будет считывать поля ввода из форм и при нажатии кнопки submit будет делать POST-запрос к Django представлению с данными, которые затем будут сохранены в базе данных postgresql. (Имейте в виду, это только личный проект)
Но при каждом запросе я получаю ошибку: Forbidden (CSRF cookie not set.). Хотя я вижу куки csrftoken на вкладке Applications в inspect. Я передаю токен csrf вместе с запросом, поэтому я не могу понять, в чем заключается ошибка.
Я пробовал получить токен csrf из cookie с помощью Cookies.get('csrftoken'), а также установить cookie для токена csrf после его получения из Django.
Вот как выглядит мое представление в Django :
@ensure_csrf_cookie
def add(request):
if request.method == "POST":
website = request.POST['website']
username = request.POST['username']
password = request.POST['password']
user = request.user
encryptedPass = cryptography.crypto(password)
credentials = Credentials.objects.create(email=username, password=encryptedPass)
if Website.objects.filter(user = user.id).filter(name=website).exists():
website_obj = Website.objects.filter(user = user.id).filter(name=website)
# print(website_obj[0].credentials)
website_obj[0].credentials.add(credentials)
else:
website_obj = Website.objects.create(user=user, name=website)
website_obj.credentials.add(credentials)
if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
return JsonResponse({'message':'Credentials Add'})
return redirect('add')
return render(request,'add.html')
Вот вид, в котором я передаю токен csrf расширению chrome:
@ensure_csrf_cookie
def get_csrf_token(request):
return JsonResponse({'csrfToken': django.middleware.csrf.get_token(request)})
Я перепробовал все в файле settings.py:
ALLOWED_HOSTS = []
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'password_manager_app'
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'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',
]
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = True
CSRF_COOKIE_SAMESITE = 'None'
SESSION_COOKIE_SAMESITE = 'None'
CSRF_COOKIE_SECURE = False
CSRF_COOKIE_HTTPONLY = False
CSRF_TRUSTED_ORIGINS = ["*"]
CSRF_ALLOWED_ORIGINS = ["*"]
CSRF_COOKIE_DOMAIN = "*"
Я делаю пост-запрос с использованием axios в моем content-script.js:
export async function getCsrfToken(){
const axios = require('axios')
let token;
const response = await axios.get('http://localhost:8000/get-csrf-token',{withCredentials:true}).then((response)=>{
console.log(response.data.csrfToken)
token = response.data.csrfToken
})
return token
}
export async function axiosaddCredentialsToDatabase(email,password,url){
const token = await getCsrfToken()
const axios = require('axios')
axios.post('http://localhost:8000/add',{email,password,url},{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': token,
'X-Requested-With': 'XMLHttpRequest',
},
withCredentials:true
}).then((response)=>{
console.log(response)
})
}
Буду признателен за любую помощь. Заранее спасибо :)
Это происходит потому, что токен каким-то образом не проходит проверку.
Кроме того, не следует посылать запрос только для получения этого токена, промежуточное программное обеспечение famework установит его как cookie, так что вам просто нужно получить его. В противном случае сервер будет перегружен запросами на получение токена (в реальных условиях).
Вот минимальный пример:
const 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();
if (cookie.substring(0, name.length + 1) === name + "=") {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
};
const csrftoken = getCookie("csrftoken");
const payload = {
email: "john.doe@example.com",
password: "supersecret",
url: "https://example.com"
};
const headers = {
"Content-Type": "application/json",
"X-CSRFToken": csrftoken,
};
const sendRequest = async () => {
try {
const response = await axios.post("/add/", payload, { headers });
console.log(response.data);
} catch (error) {
console.log(error);
}
};
sendRequest();
views.py
@ensure_csrf_cookie
def add(request):
if request.method == "POST":
data = json.loads(request.body)
url = data["url"]
email = data["email"]
password = data["password"]
# Do your thing
...
return JsonResponse({"message": "Credentials Add"})
return render(request, "add.html")