Skip to content

Commit 76a609f

Browse files
committed
commit d4f5e6b7a8c9d0e1f2g3h4i5j6k7l8m9n0o1p2q3
1 parent 01df373 commit 76a609f

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

backend/accounts/auth_views.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from django.utils.decorators import method_decorator
66
from django.views.decorators.csrf import csrf_protect, ensure_csrf_cookie
77
from rest_framework import permissions, status
8+
from rest_framework.authentication import BaseAuthentication
89
from rest_framework.response import Response
910
from rest_framework.throttling import ScopedRateThrottle
1011
from rest_framework.views import APIView
@@ -34,6 +35,12 @@ def _cookie_params() -> dict:
3435

3536
class CsrfView(APIView):
3637
permission_classes = [permissions.AllowAny]
38+
# IMPORTANT:
39+
# DRF runs authentication before permission checks. Our default auth backend
40+
# (`CookieJWTAuthentication`) loads the user from the database, which means
41+
# even this public endpoint will fail hard if the DB is unreachable.
42+
# CSRF token issuance should not depend on the DB.
43+
authentication_classes: list[type[BaseAuthentication]] = []
3744

3845
@method_decorator(ensure_csrf_cookie)
3946
def get(self, request):

frontend/src/pages/Register.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useState } from 'react';
22
import { Link, useNavigate, useLocation } from 'react-router-dom';
3-
import api from '../services/api';
3+
import api, { setCsrfToken } from '../services/api';
44
import SearchableCountryDropdown from '../components/SearchableCountryDropdown';
55

66
const Register = () => {
@@ -47,7 +47,8 @@ const Register = () => {
4747
setLoading(true);
4848

4949
try {
50-
await api.get('/auth/csrf/');
50+
const csrfResp = await api.get('/auth/csrf/');
51+
if (csrfResp?.data?.csrfToken) setCsrfToken(csrfResp.data.csrfToken);
5152
await api.post('/accounts/register/', {
5253
username: formData.username,
5354
email: formData.email,
@@ -62,13 +63,32 @@ const Register = () => {
6263
navigate('/login', { state: { email: formData.email, from: location.state?.from } });
6364
}, 2000);
6465
} catch (err) {
65-
if (err.response?.data) {
66-
const errorMessages = Object.entries(err.response.data)
67-
.map(([key, value]) => `${key}: ${Array.isArray(value) ? value[0] : value}`)
68-
.join(', ');
69-
setError(errorMessages);
66+
if (!err?.response) {
67+
setError('Cannot reach the API server. Please try again later.');
68+
} else if (err.response?.status === 429) {
69+
setError('Too many attempts. Please wait and try again.');
7070
} else {
71-
setError('Failed to create account. Please try again.');
71+
const data = err.response?.data;
72+
73+
// If the backend returns an HTML error page (common when DEBUG=True),
74+
// avoid exploding it into thousands of characters.
75+
if (typeof data === 'string') {
76+
const trimmed = data.trim().toLowerCase();
77+
if (trimmed.startsWith('<!doctype html') || trimmed.startsWith('<html')) {
78+
setError('Server error while creating account. Please try again later.');
79+
} else if (data.length > 300) {
80+
setError('Server error while creating account. Please try again later.');
81+
} else {
82+
setError(data);
83+
}
84+
} else if (data && typeof data === 'object') {
85+
const errorMessages = Object.entries(data)
86+
.map(([key, value]) => `${key}: ${Array.isArray(value) ? value[0] : value}`)
87+
.join(', ');
88+
setError(errorMessages || 'Failed to create account. Please try again.');
89+
} else {
90+
setError('Failed to create account. Please try again.');
91+
}
7292
}
7393
} finally {
7494
setLoading(false);

0 commit comments

Comments
 (0)