Skip to main content

DRF authentication for Auth.js with database adapter

Project description

DRF authentication for Authjs with database adapter

This app is used to integrate Authjs authentication with a Django + DRF project. It can create the DB to be used as with the AuthJs adapter and provides an authentication class based on that. Instead of reauthenticating users with sessions or JWT, it matches the Authjs token sent in the Authorization header with the contents of the database used by Authjs.

Usage

Frontend

In the frontend, use Authjs with a database adapter. In this example, we'll be using the pg adapter for PostgreSQL.

import NextAuth from "next-auth";
import { Pool } from "pg";
import MyProvider from "next-auth/providers/myprovider"; // Example: google

const pool = new Pool({
  host: process.env.DATABASE_HOST,
  user: process.env.DATABASE_USER,
  password: process.env.DATABASE_PASSWORD,
  database: process.env.DATABASE_NAME,
})

export const { auth, handlers, signIn, signOut } = NextAuth({
 providers: [MyProvider],
});

You'll also need to send the session token which each request to the backend.

import { auth } from "@/auth";

const session = await auth();

const data = await fetch("/api/some-protected-endpoint", {
  headers: {
    "Authorization": `Bearer ${session.token}`,
  },
});

Backend

Since we need to adapt the table schema to match authjs's, we recommend using a separate database for the Authjs tables. In the settings.py file, configure a new database connection for Authjs. Be sure to use the same values as the ones passed to the frontend.

# settings.py

import os

...

DATABASES = {
    ...
    "authjs": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": os.getenv("AUTHJS_DATABASE_NAME"),
        "USER": os.getenv("AUTHJS_DATABASE_USER"),
        "PASSWORD": os.getenv("AUTHJS_DATABASE_PASSWORD"),
        "HOST": os.getenv("AUTHJS_DATABASE_HOST"),
        "PORT": os.getenv("AUTHJS_DATABASE_PORT"),
    },
}

Configure this app to use the created database connection.

# settings.py

...

AUTHJS_DATABASE = "authjs"

Put this package in your INSTALLED_APPS:

# settings.py
INSTALLED_APPS = [
    ...
    "drf_authjs_db_auth",
    ...
]

And run migrations to create the necessary tables (be sure that the database exists beforehand, if not using sqlite):

python manage.py migrate drf_authjs_db_auth --database authjs
python manage.py migrate drf_authjs_db_auth --fake # (avoid warnings about unnapplied migrations)

You can fake both migrations if the database already exists (though we do introduce an extra text column username in the user table, make sure it is present).

Finally, set up the rest framework authentication backend to use Authjs authentication:

# settings.py

REST_FRAMEWORK = {
    ...
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "drf_authjs_db_auth.authentication.AuthJSAuthentication",
        ...
    ],
    ...
}

Getting user data from the backend

If you need additional user information from the backend, you can create a custom user seralizer and read it with authjs's session callback. Example user serializer and view:

from rest_framework import serializers
from django.contrib.auth import get_user_model

UserModel = get_user_model()

class UserDetailsSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserModel
        fields = ('pk', 'username', 'email', 'first_name', 'last_name')
        read_only_fields = ('email', 'pk')
from rest_framework.generics import RetrieveAPIView
from rest_framework.permissions import IsAuthenticated

class UserDetailsView(RetrieveAPIView):
    serializer_class = UserDetailsSerializer
    permission_classes = (IsAuthenticated,)

    def get_object(self):
        return self.request.user

For more elaborate examples, check dj_rest_auth's user serializer and user view.

Then, in the frontend, you can append the user data to the session in the NextAuth session callback:

import { auth } from "@/auth";

export const { auth, handlers, signIn, signOut } = NextAuth({
  ...,

  callbacks: {
    async session({ session }) {
      if (session && !session.user?.username) {
        const data = await getUserData(session); // Fetch from your user details endpoint
        session.user.username = data.username;
        session.user.pk = data.pk;
      }

      return session;
    },
  },
})

Contributing

  • Sync packages with uv sync --all-packages;
  • Use mypy to type check;
  • MR to the repository.

Needs doing

  1. Adding an example frontend project (maybe using authjs's example repository for NextJS)
  2. Test behavior and document for different database adapters (Prisma
    • SQLite for example).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

drf_authjs_db_auth-0.1.0.tar.gz (23.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

drf_authjs_db_auth-0.1.0-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

File details

Details for the file drf_authjs_db_auth-0.1.0.tar.gz.

File metadata

  • Download URL: drf_authjs_db_auth-0.1.0.tar.gz
  • Upload date:
  • Size: 23.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.15

File hashes

Hashes for drf_authjs_db_auth-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bece82dfebfe4aca711740019baf2bc0aa93f6b4f4a1ea9dcecad7deefaf22a4
MD5 5a8cef2daed41cf82477617ca7271d00
BLAKE2b-256 de85aba9875744264113462cc60334a11109b91215d9c510938659373bc81253

See more details on using hashes here.

File details

Details for the file drf_authjs_db_auth-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for drf_authjs_db_auth-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7976bcee43716cbbdea09b9d9bdeed215cdc657984c1dc3e12e73cc5890ad2e9
MD5 5c4f7ea1f9759f5c3db6ae04f8c56cb0
BLAKE2b-256 1010b1175a4a7c652c7e8027330af75ad0d9aece89ff92b27f17dc77594c9c2d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page