Проверка CSRF не удалась. Запрос прерван. только для страницы входа в систему
Я создаю приложение To-Do в качестве своего первого проекта в django.
Все работает нормально, когда я запускаю на локальном сервере, но когда я развертываю его на heroku, CSRF токен не работает только на странице входа. Приложение развернуто здесь.
Проблема: Если мы попробуем любого случайного или существующего пользователя на странице входа в систему, он показывает, что проверка CSRF не удалась BUT если мы открываем /register конечную точку, т.е. регистрируем пользователя в приложении, он создает пользователя и правильно входит в систему в это время. Все функции приложения, такие как добавление новой задачи, редактирование задачи, удаление задачи, работают нормально до тех пор, пока я logout не зарегистрирую этого пользователя.
Когда я снова возвращаюсь на страницу входа, я не могу войти ни под одной учетной записью пользователя.
Я пробовал много различных методов, таких как службы в Procfile, переменные окружения для SECRET_KEY, обеспечение тега meta в main.html для токена csrf с помощью content={{ csrf_token }}, но безуспешно.
Коды:
settings.py
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.getenv('DEBUG', False)
ALLOWED_HOSTS = [
'.herokuapp.com',
'127.0.0.1:8000'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware', Commented or not commented, it doesn't matter... issue still persists
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
views.py для страницы входа и регистрации
class CustomLoginView(LoginView):
template_name = 'app/login.html'
fields = '__all__'
redirect_authenticated_user = True
def get_success_url(self):
return reverse_lazy('tasks')
class RegisterView(FormView):
template_name = 'app/register.html'
form_class = UserCreationForm
success_url = reverse_lazy('login')
def form_valid(self, form):
user = form.save()
if user is not None:
login(self.request, user)
return super(RegisterView, self).form_valid(form)
def get(self, *args, **kwargs):
if self.request.user.is_authenticated:
return redirect('tasks')
return super(RegisterView, self).get(*args, **kwargs)
main.html
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Nunito:wght@200&display=swap"
rel="stylesheet"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
rel="shortcut icon"
href="https://raw.githubusercontent.com/HemantSachdeva/JokeApi/main/src/static/assets/favicon.ico"
/>
<link rel="stylesheet" href="{% static 'style/main.css' %}">
<title>To Do Tasks</title>
</head>
<body>
<div class="container">{% block content %} {% endblock %}</div>
</body>
</html>
login.html
{% extends 'app/main.html' %} {% block content %}
<div class="header-bar">
<h1>Login</h1>
</div>
<div class="card-body">
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input class="button" type="submit" value="Login" />
</form>
<p>Don't have an account? <a href="{% url 'register' %}">Register</a></p>
</div>
{% endblock content %}
register.html
{% extends 'app/main.html' %} {% block content %}
<div class="header-bar">
<h1>Register</h1>
</div>
<div class="card-body">
<form method="POST">
{% csrf_token %}
<label> {{ form.username.label }} <span style="color: red">*</span> </label>
{{ form.username }}
<ul>
<li>150 characters or fewer.</li>
<li>Letters, digits and @ - + _ . only.</li>
</ul>
<label> {{ form.password1.label }} </label>
{{ form.password1 }} {{ form.password1.help_text }}
<label> Confirm Password </label>
{{ form.password2 }} <br />
{{ form.password2.help_text }}
<input
style="margin-top: 10px"
class="button"
type="submit"
value="Register"
/>
</form>
<p>Already have an account? <a href="{% url 'login' %}">Login</a></p>
</div>
{% endblock content %}
task.html (где он должен приземлиться после успешного входа в систему)
{% extends 'app/main.html' %} {% block content %}
<div class="header-bar">
<div>
<h1>Hello {{ request.user|capfirst }}</h1>
<h3 style="margin: 0">
You have <i>{{ count }}</i> incomplete task{{ count|pluralize:"s" }}.
</h3>
</div>
{% if request.user.is_authenticated %}
<a href="{% url 'logout' %}">Logout</a>
{% endif %}
</div>
<div id="search-add-wrapper">
<form method="GET" style="margin-top: 20px; display: flex">
<input type="text" name="search" value="{{ search_input }}" />
<input class="button" type="submit" value="Search" />
</form>
<a id="add-link" href="{% url 'task_new' %}">+</a>
</div>
<div class="task-items-wrapper">
{% for task in tasks %}
<div class="task-wrapper">
{% if task.complete %}
<div class="task-title">
<div class="task-complete-icon"></div>
<i>
<s> {{ task|capfirst }} </s>
</i>
</div>
<p>
<a href="{% url 'task_edit' task.id %}"
><i class="fa fa-edit" style="margin-right: 10px"></i
></a>
<a class="delete-link" href="{% url 'task_delete' task.id %}">×</a>
</p>
{% else %}
<div class="task-title">
<div class="task-incomplete-icon"></div>
{{ task|capfirst }}
</div>
<p>
<a href="{% url 'task_edit' task.id %}"
><i class="fa fa-edit" style="margin-right: 10px"></i
></a>
<a class="delete-link" href="{% url 'task_delete' task.id %}">×</a>
</p>
{% endif %}
</div>
{% empty %}
<p>No task found.</p>
{% endfor %}
</div>
{% endblock content %}
Я никогда не использовал DEBUG=True перед тем, как опубликовать этот вопрос, и ошибка была четко видна после его использования.
Ошибка:
Origin checking failed - https://hemant-to-do.herokuapp.com does not match any trusted origins.
Решение:
добавлено следующее в settings.py
CSRF_TRUSTED_ORIGINS = [
'https://hemant-to-do.herokuapp.com'
]