Overview
Authentication system using djoser, SimpleJWT and django-allauth.
HyperSaaS uses three libraries for authentication:
| Library | Purpose |
|---|---|
| djoser | REST endpoints for sign-up, activation, password reset, email change and account deletion |
| djangorestframework-simplejwt | JWT access and refresh tokens |
| django-allauth | Server-side account pages, and the Django admin's sign-in when DJANGO_ADMIN_FORCE_ALLAUTH=True |
The Next.js frontend signs people in with email and password through these endpoints. There is no server-rendered sign-up: allauth's own sign-up pages are closed unless you set DJANGO_ACCOUNT_ALLOW_REGISTRATION=True, because an account created there would skip the API's activation flow.
Authentication Method
The REST API accepts JWTs only:
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
),
"DEFAULT_PERMISSION_CLASSES": (
"rest_framework.permissions.IsAuthenticated",
),
}Send the access token as Authorization: JWT <access_token>. See JWT Tokens for lifetimes and refresh.
Custom User Model
HyperSaaS uses email as the identifier instead of a username:
class User(AbstractUser):
name = models.CharField(max_length=255, blank=True)
email = models.EmailField(unique=True)
USERNAME_FIELD = "email"
class Meta:
constraints = [
models.UniqueConstraint(Lower("email"), name="users_user_email_unique_ignoring_case"),
]Emails are stored lowercase and looked up case-insensitively, so Ana@Example.com and ana@example.com are the same account.
Rate Limits
Signing in, signing up, activation, password and email resets, and password changes are limited per account: by the email or uid in the request, not by IP.
| Setting | Default | Covers |
|---|---|---|
THROTTLE_AUTH_ATTEMPTS | 10/minute | POST /auth/jwt/create/ and djoser's account endpoints |
That stops guessing at one account's password and repeated emails to one address. Limiting by IP would lock everyone out at once, since the Next.js server makes these calls for all users. Over the limit, the API returns 429.
Password reset and email reset answer the same whether or not the address is registered, so they can't be used to find out who has an account.
Password Hashing
HyperSaaS uses Argon2 as the primary password hasher:
PASSWORD_HASHERS = [
"django.contrib.auth.hashers.Argon2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
"django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
]