JSON Web Token for Django GraphQL

0.4.0 · active · verified Fri Apr 17

django-graphql-jwt is a Python library that provides JSON Web Token (JWT) authentication for Django GraphQL applications. It integrates seamlessly with graphene-django and Django's authentication system, offering mutations for obtaining, refreshing, and verifying tokens, as well as decorators and mixins for protecting GraphQL views and fields. It is currently at version 0.4.0 and typically releases updates as needed, often tied to major versions of Django, Graphene-Django, or PyJWT.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define a basic `django-graphql-jwt` schema with `ObtainJSONWebToken`, `VerifyToken`, and `RefreshToken` mutations. It includes a minimal, self-contained Django environment setup to make the code runnable, creating a test user and then executing sample GraphQL mutations to obtain and verify a token. For a full Django project, you would integrate `AUTHENTICATION_BACKENDS` and `MIDDLEWARE` into your project's `settings.py` and expose the schema via `graphene_django.views.GraphQLView`.

import graphene
import graphql_jwt
from django.conf import settings
from django.core.management import call_command
from django.contrib.auth import get_user_model

# Minimal Django settings for a runnable example
if not settings.configured:
    settings.configure(
        SECRET_KEY='a-very-secret-key-for-testing',
        DEBUG=True,
        ALLOWED_HOSTS=['*'],
        INSTALLED_APPS=[
            'django.contrib.admin',
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'django.contrib.sessions',
            'django.contrib.messages',
            'django.contrib.staticfiles',
            'graphene_django',
            'graphql_jwt',
        ],
        AUTHENTICATION_BACKENDS=[
            'graphql_jwt.backends.JSONWebTokenBackend',
            'django.contrib.auth.backends.ModelBackend',
        ],
        MIDDLEWARE=[
            'django.middleware.security.SecurityMiddleware',
            'django.contrib.sessions.middleware.SessionMiddleware',
            'django.middleware.common.CommonMiddleware',
            'django.middleware.csrf.CsrfViewMiddleware',
            'django.contrib.auth.middleware.AuthenticationMiddleware',
            'django.contrib.messages.middleware.MessageMiddleware',
            'django.middleware.clickjacking.XFrameOptionsMiddleware',
            'graphql_jwt.middleware.JSONWebTokenMiddleware',
        ],
        ROOT_URLCONF=__name__, # Simplistic for example
        TEMPLATES=[{ # Required for admin to work minimally
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [], 'APP_DIRS': True,
            'OPTIONS': {'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ]}},
        ],
        DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
        GRAPHQL_JWT={ # Example custom settings
            'JWT_VERIFY_EXPIRATION': True,
            'JWT_EXPIRATION_DELTA': 'datetime.timedelta(minutes=5)',
            'JWT_REFRESH_EXPIRATION_DELTA': 'datetime.timedelta(days=7)',
        }
    )
    # Apply migrations for auth models
    call_command('migrate', verbosity=0, interactive=False)

# Create a dummy user for the example
User = get_user_model()
try:
    User.objects.get(username='testuser')
except User.DoesNotExist:
    user = User.objects.create_user(username='testuser', email='test@example.com', password='password123')

# Define your GraphQL schema
class Query(graphene.ObjectType):
    hello = graphene.String(name=graphene.String(default_value="World"))

    def resolve_hello(self, info, name):
        return f"Hello {name}!"

# Custom mutation for obtaining token with user info
class ObtainJSONWebToken(graphql_jwt.JSONWebTokenMutation):
    user = graphene.Field(User.__class__)

    @classmethod
    def resolve_mutant(cls, root, info, **kwargs):
        return cls(user=info.context.user)

# Custom mutation for refreshing token with user info
class RefreshToken(graphql_jwt.RefreshTokenMutation):
    user = graphene.Field(User.__class__)

    @classmethod
    def resolve_mutant(cls, root, info, **kwargs):
        return cls(user=info.context.user)

# Custom mutation for verifying token with user info
class VerifyToken(graphql_jwt.VerifyTokenMutation):
    user = graphene.Field(User.__class__)

    @classmethod
    def resolve_mutant(cls, root, info, **kwargs):
        return cls(user=info.context.user)


class Mutation(graphene.ObjectType):
    token_auth = ObtainJSONWebToken.Field()
    verify_token = VerifyToken.Field()
    refresh_token = RefreshToken.Field()

schema = graphene.Schema(query=Query, mutation=Mutation)

# Example usage (run a mutation against the schema)
if __name__ == "__main__":
    print("\n--- Attempting to obtain token ---")
    obtain_token_query = """
        mutation ObtainToken {
            tokenAuth(username: "testuser", password: "password123") {
                token
                user {
                    username
                    email
                }
            }
        }
    """
    result = schema.execute(obtain_token_query)
    if result.errors:
        print("Errors:", result.errors)
    else:
        print("Data:", result.data)
        token = result.data['tokenAuth']['token']

        print("\n--- Attempting to verify token ---")
        verify_token_query = f"""
            mutation VerifyToken {{
                verifyToken(token: "{token}") {{
                    payload
                    user {{
                        username
                    }}
                }}
            }}
        """
        result_verify = schema.execute(verify_token_query)
        if result_verify.errors:
            print("Errors:", result_verify.errors)
        else:
            print("Data:", result_verify.data)

view raw JSON →