reCAPTCHA
The login, signup and password reset request forms are protected by Google reCAPTCHA v3 through django-recaptcha.
reCAPTCHA v3 is invisible: there is no checkbox and no challenge. On submit, a
Google script attaches a single-use token to the form; the server asks Google
for the token's score (0.0 = bot, 1.0 = human) and rejects the form with an
error message when the score is below RECAPTCHA_REQUIRED_SCORE, or when the
token is missing (script blocked or not loaded).
The captcha is disabled when RECAPTCHA_PUBLIC_KEY is empty: the field is
not added to the forms, so local development and the test suite need neither
keys nor network. The same holds in production - without keys, the forms work
unprotected.
Not covered: the MFA step, the reset link received by email, the signup that follows a Google or Microsoft login, and the anonymous questionnaire.
Creating the key
- Open the Google Cloud Console and select the project that already holds the OAuth credentials (see Authentication and Google OAuth).
- Go to Security → reCAPTCHA (also labelled Fraud Defense), tab Keys, and click Create key.
- Fill in the form:
- a display name, e.g.
sad-pulm; - application type Web;
- the domain list:
sad-pulm.he-arc.ch, pluslocalhostto try the key locally; - key type Score-based (the default);
- leave the testing purposes only toggle off.
- a display name, e.g.
- Click Create. The key ID shown is the site key (public).
- Open Key details → Integration → Use legacy key to get the secret key.
Configuring the project
On the server, in .envs/.production/.django:
RECAPTCHA_PUBLIC_KEY=the-site-key
RECAPTCHA_PRIVATE_KEY=the-legacy-secret-key
RECAPTCHA_REQUIRED_SCORE=0.5
Then redeploy. RECAPTCHA_REQUIRED_SCORE is optional and defaults to 0.5;
raise it to be stricter, lower it if legitimate users get rejected.
Warning
.envs/.local/.django is tracked by git. To try the captcha locally, put
the keys there, but never commit them. The test suite is unaffected:
config/settings/test.py empties the keys.
Quota and monitoring
The first 10,000 verifications per month are free; billing only starts beyond
that. The Google Cloud Console shows, per key, the number of verifications and
the score distribution for each action (login, signup, password_reset) -
look there before changing the threshold.
Admin login
The Django admin has its own login form, which carries no captcha. In production, set
so that /<DJANGO_ADMIN_URL>/ redirects to the allauth login page and admins
go through the same captcha, rate limits and MFA as everyone else.
Templates
sad_pulm/templates/account/snippets/recaptcha_notice.html- the "protected by reCAPTCHA" notice shown under the forms. Google requires it because the floating badge is hidden (.grecaptcha-badgeinfrontend/src/scss/styles.scss).sad_pulm/templates/allauth/elements/form.html- allauth's form element, overridden to append the notice to every form that carries the captcha field.