Credentials provider¶
Email/password authentication with Argon2 hashing and brute-force lockout.
from fastauth.providers.credentials import CredentialsProvider
provider = CredentialsProvider() # default
provider = CredentialsProvider(max_login_attempts=10, lockout_duration=600)
Constructor args control the fallback lockout thresholds, but FastAuthConfig.security (SecurityConfig) takes precedence when both are set.
Endpoints¶
| Method | Path | Request | Response |
|---|---|---|---|
| POST | /auth/register |
{email, password, name?} |
201 TokenResponse (JSON) or MessageResponse (cookie); 409 if email exists |
| POST | /auth/login |
{email, password, remember=false} |
TokenResponse or MessageResponse; 401 on bad credentials |
| POST | /auth/logout |
— | {message} (requires auth) |
Password hashing¶
hash_password and verify_password use Argon2 (argon2-cffi). Passwords are validated against FastAuthConfig.password on /auth/register and /auth/reset-password; failure returns 400 with the validation message.
Account lockout¶
CredentialsProvider.authenticate throttles by email (always) and optionally by client IP (security.login_attempts_by_ip=True). When failures exceed security.max_login_attempts (default 5), the account key is locked for security.lockout_duration (default 300s). Further login attempts during lockout raise AccountLockedError carrying the remaining seconds. State is persisted via token_adapter (type "login_attempt"); without one, in-process memory is used (non-production fallback controlled by security.use_memory_login_attempts_without_token_adapter).
Hooks¶
on_signup— fires on/auth/register.on_signin— fires on successful/auth/login(provider="credentials").on_signout— fires on/auth/logout.
allow_signinis NOT called on/auth/login. It is only invoked by OAuth, magic-link, and passkey. If you need to gate credentials login (e.g. onemail_verified), do it in your own route wrapper.
Email verification¶
Registration does not send a verification email. The user must explicitly call POST /auth/request-verify-email. See Email verification.
Common mistakes¶
400 Credentials provider is not configuredon/auth/register— remove a strayCredentialsProviderfrom the providers list, or add it back.401 Invalid email or passwordon a freshly registered user — you sentpasswordfrom the request body but the password field is hashed; retype the original password.- Lockout persists after you fix the bug —
login_attemptrecords have a 15-minute TTL between lockouts. Clear viatoken_adapter.delete_user_tokens(user_id, "login_attempt").