Problème de vérification CSRF lors de la connexion Django
Hello tout le monde! :)
Je bute ici sur une problématique qui de base me semblait simple, mais sur laquelle je bloque complètement.
Pour le contexte:
J'essaie simplement de me logger sur mon appli Django (avec username et password).
Après avoir soumis le formulaire, j'obtiens l'erreur suivante:
Interdit (403)
La vérification CSRF a échoué. La requête a été interrompue.
Ma vue de login:
def login_user(request):
""" Perform user authentication via the web UI. """
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
user = authenticate(
username=form.cleaned_data['username'],
password=form.cleaned_data['password'],
)
if user is not None:
login(request, user)
messages.add_message(request, messages.SUCCESS, 'Welcome!')
logger.info(f'authentication succeeded for user "{user.username}"')
return redirect('homepage')
messages.add_message(request, messages.ERROR, 'Login failed!')
else:
form = LoginForm()
return render(request, 'accounts/login.html', context={'form': form})
Le formulaire utilisé:
class LoginForm(forms.Form):
username = forms.CharField(max_length=50)
password = forms.CharField(max_length=50, widget=forms.PasswordInput())
Et enfin, le template (qui comporte pourtant bien le tag {% csrf_token %}):
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Login | dashboard {% endblock title %}
{% block content %}
<div class="container">
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-primary" type="submit">Login</button>
</form>
</div>
{% endblock content %}
En cherchant un peu (notamment sur la doc Django), je suis tombé sur ça:
https://docs.djangoproject.com/en/5.1/howto/csrf/
avec tout un tas d'étapes que je n'avais jamais eu besoin de réaliser auparavant.
Je suis un peu perdu pour le coup...
Si qqn est dispo pour une petite explication, je suis preneur! :)
Non, le filtre crispy n'ajoute pas le token. Dans tout les cas, je te recommande de tester avec la LoginView, car ta vue n'implémente pas complètement le comportement attendu d'une vue de connection. Techniquement, je ne vois pas d'erreur au niveau du CSRF.
En reproduisant ton code local, je confirme qu'il n'y a aucun problème avec ce dernier.
Pour implémenter l'équivalent de la LoginView de Django, n'oublie pas la gestion du next:
def login_user(request):
""" Perform user authentication via the web UI. """
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
user = authenticate(
username=form.cleaned_data['username'],
password=form.cleaned_data['password'],
)
if user is not None:
login(request, user)
messages.success(request, 'Welcome!')
logger.info(f'authentication succeeded for user "{user.username}"')
if 'next' in request.GET:
return redirect(request.GET['next'])
return redirect('homepage')
messages.error(request, 'Login failed!')
else:
form = LoginForm()
return render(request, 'accounts/login.html', context={'form': form})
@Gabriel
Oui, j'ai bien le MiddleWare suivant dans mon fichier de settings:
"django.middleware.csrf.CsrfViewMiddleware",
@Thibault
A priori, je n'ai bien qu'un seul csrftoken en inspectant la page.
@Thierry
Merci pour la correction concernant le next. Je ne l'avais pas du tout vu... :/
Je vais passer par la LoginView directement comme suggéré.
Concernant mon erreur de CSRF Token, ça semble un peu aléatoire. Ce matin je n'ai plus le soucis (après redémarrage donc, car toujours en environnement de test sur mon poste).
Je commence à me poser des questions côté navigateur également: j'utilise Chromium pour les tests, et LibreWolf (dérivé de Firefox) pour la navigation. Or, ce matin, depuis Chromium, impossible de me connecter à l'appli Django alors que celle-ci est bien démarrée. Depuis LibreWolf, aucun soucis..... :/
Après, je vois pas autre chose en particulier à faire sur ce sujet.
C'était peut-être tout simplement lié à mon navigateur.
Maintenant, j'ai plus de difficultés à gérer la connexion Utilisateur que je ne pensais (peut être une prochaine question en perspective!).
Merci beaucoup pour votre aide! :)
Inscris-toi
(c'est gratuit !)
Tu dois créer un compte pour participer aux discussions.
Créer un compte