I can’t stress this enough, Django csrf need a rework, it sucks so much, the problem im going to relate below is in a production enviroment:
What is happening exactly is that im able to generate the csrftoken it is being set in the request headers, but when I try to actually login I get a CSRF token missing;
error.
IN DEVELOMENT THIS IMPLEMENTATION WORKS
Backend:
settings.py
MIDDLEWARE = [
"whitenoise.middleware.WhiteNoiseMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
CORS_ALLOWED_ORIGINS = ["app.link"]
CSRF_TRUSTED_ORIGINS = ["app.link"]
CSRF_COOKIE_NAME = "csrftoken"
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework.authentication.SessionAuthentication",
),
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
"DEFAULT_FILTER_BACKENDS": ("django_filters.rest_framework.DjangoFilterBackend",),
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
"PAGE_SIZE": 10,
}
account/views.py
@method_decorator(csrf_protect, name="dispatch")
class Login(APIView):
permission_classes = (permissions.AllowAny,)
def post(self, request, format=None):
"""Login"""
email = request.data["email"]
password = request.data["password"]
try:
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
if user.type == "A":
serializer = AdminSerializer(user.admin)
elif user.type == "P":
serializer = PersonSerializer(user.person)
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(status=status.HTTP_401_UNAUTHORIZED)
except:
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Frontend:
api/api.config.ts
import axios from "axios";
const api = axios.create({
baseURL: "app.link",
});
api.defaults.xsrfCookieName = "csrftoken";
api.defaults.xsrfHeaderName = "X-CSRFToken";
api.defaults.withCredentials = true;
export default api;
pages/admin.tsx
const handleLoginAdmin = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
return api.get("auth/csrf").then(async (response) => {
if (response.status !== 200) throw new Error(response.statusText);
await api.post("auth/login", data).then((response) => {
if (response.status !== 200) throw new Error(response.statusText);
const { id, group, role } = response.data;
setCurrentAdmin({ id, group, role });
router("/clinic");
});
});
} catch (error) {
setError("Erro ao fazer login");
return Promise.reject();
}
};
Requests: