Migrate an existing Django auth API from dj-rest-auth to django-modern-rest, moving account flows onto django-allauth headless and rebuilding the transport layer with dmr controllers and auth classes. Use when replacing dj_rest_auth login/logout/registration/password/MFA/social views and their DRF serializers.
73
90%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Migrate a dj-rest-auth installation to django-modern-rest.
Required docs (always reference first):
This migration is not shaped like $dmr-from-drf.
dj-rest-auth is a DRF layer on top of django-allauth. We do not
reimplement account management. django-allauth keeps owning registration,
email verification, password reset, social login, MFA, and passkeys through
its headless mode, and django-modern-rest owns your own API surface plus
the auth classes that read allauth's credentials.
Three consequences the user must accept before any code is written:
/_allauth/{client}/v1/... routes. Strict path parity is not a goal
and usually not achievable.status, data, meta) and its own error format.If the user cannot change clients, stop and say so. A compatibility shim
that re-serves dj-rest-auth paths and payloads is possible but is a
long-lived maintenance burden. Do not build one silently.
behavioral parity, not transport parity.
The same things must be possible; the wire format may differ.approved drift and must be
listed explicitly. Never let a drift pass unlisted just because
the endpoint "still works".dj_rest_auth in INSTALLED_APPS and its URL includes
(dj_rest_auth.urls, dj_rest_auth.registration.urls, dj_rest_auth.mfa.urls).REST_AUTH setting in use, they encode real requirements.
See the settings table in the local map.LOGIN_SERIALIZER, REGISTER_SERIALIZER, USER_DETAILS_SERIALIZER, ...).
These are where projects hide their custom business rules.authtoken, simplejwt
with headers, simplejwt with cookies, or session login.django-allauth is already installed and configured,
which it usually is.dj-rest-auth is often customized by subclassing. Before mapping anything,
list for each overridden serializer or view:
Side effects are the part most likely to be lost silently. Each one must be re-attached to an allauth signal or to your own controller.
Pick one and record it. See the auth table in the local map.
XSessionTokenSyncAuthAuthorization header -> HeaderJWTSyncAuthCookieJWTSyncAuthHeaderTokenSyncAuth and the dmr token appDjangoSessionSyncAuthMatch the existing security posture. A project on JWT_AUTH_HTTPONLY
cookies must not be silently moved to header tokens readable by JavaScript.
allauth, allauth.account, allauth.headless to INSTALLED_APPS
and allauth.account.middleware.AccountMiddleware to MIDDLEWARE.app or browser client deliberately:
app uses X-Session-Token, browser uses session cookies.ACCOUNT_* settings so the account rules
(email verification, unique email, signup fields) stay the same.external_path(),
allauth publishes its own specification.Migrate one flow at a time, in this order, because later flows depend on being able to log in:
For each flow: map the endpoint, port custom validation and side effects, update the client, update tests, then run the repository's checks.
allauth headless has no user-details endpoint. rest_user_details becomes
your own Controller over your user model, with typed DTOs.
This is normal, and it is the right place for project-specific profile
fields that never belonged in an auth library.
TypedDict is the default for reusable controllers in this project.@sensitive_post_parameters to anything accepting credentials.@sensitive_variables() to every method that holds credentials
or tokens in its local variables, so they never reach error reports.
Async methods need it on each coroutine, sync ones also cover their callees.NO_STORE_HEADERS from dmr.security in @modify for any view
that issues or accepts credentials.JWT_AUTH_COOKIE), keep them as cookies
with the same flags: httponly, secure, samesite, and the refresh
cookie's path. Do not downgrade them.dmr enforces CSRF automatically for cookie-based auth,
which replaces JWT_AUTH_COOKIE_USE_CSRF.CookieSpec so response validation
and the OpenAPI schema stay honest.httponly is a silent security regression that no
happy-path test will catch.validate_responses in development and testing.Do not mark a flow done until linters pass, tests pass, the client is updated, and the report is updated.
dj_rest_auth or DRF imports in migrated modules.At each checkpoint and at completion, report in 4 sections:
preserved behaviorapproved drift (paths, payloads, statuses, client changes)security posture changesunresolved gapssecurity posture changes is separate on purpose. It must state explicitly
when cookie flags, CSRF behavior, token lifetime, or token visibility
to JavaScript changed, even if the user already approved it.
dj-rest-auth logout has two behaviors depending on SESSION_LOGIN and
token strategy. Verify what the deployment actually does before mapping it.LOGOUT_ON_PASSWORD_CHANGE silently invalidates sessions.
allauth's behavior differs; check it rather than assuming.OLD_PASSWORD_FIELD_ENABLED controls whether the current password is
required. Turning this off during migration is a security regression.JWT_AUTH_* settings loses the cookie flags,
because they become arguments to NewCookie, not settings.REGISTER_SERIALIZER side effects (provisioning, invites, billing)
disappear unless re-attached to allauth signals.simplejwt refresh-token rotation and blacklisting are not automatic
in dmr. Use the dmr jwt blocklist app if the project relied on it.dj_rest_auth imports remain.dj-rest-auth, and djangorestframework if nothing
else needs it, from project dependencies.87a02f5
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.