Skip to main content

JSON Web Token for Django GraphQL

Project description

Pypi Wheel Build Status Codecov Code Climate

JSON Web Token authentication for Django GraphQL

Dependencies

  • Django ≥ 1.11

Installation

Install last stable version from Pypi.

pip install django-graphql-jwt

Include the JSONWebTokenMiddleware middleware in your MIDDLEWARE settings:

MIDDLEWARE = [
    ...
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'graphql_jwt.middleware.JSONWebTokenMiddleware',
    ...
]

Include the JSONWebTokenBackend backend in your AUTHENTICATION_BACKENDS settings:

AUTHENTICATION_BACKENDS = [
    'graphql_jwt.backends.JSONWebTokenBackend',
    'django.contrib.auth.backends.ModelBackend',
]

Schema

Add mutations to the root schema.

import graphene
import graphql_jwt


class Mutations(graphene.ObjectType):
    token_auth = graphql_jwt.ObtainJSONWebToken.Field()
    verify_token = graphql_jwt.Verify.Field()
    refresh_token = graphql_jwt.Refresh.Field()

schema = graphene.Schema(mutation=Mutations)
  • tokenAuth to authenticate the user and obtain the JSON Web Token.

The mutation uses your User’s model USERNAME_FIELD, which by default is username.

mutation TokenAuth($username: String!, $password: String!) {
  tokenAuth(username: $username, password: $password) {
    token
  }
}
  • verifyToken to confirm that the token is valid.

mutation VerifyToken($token: String!) {
  verifyToken(token: $token) {
    payload
  }
}
  • refreshToken to refresh the token.

Configure your refresh token scenario and set to True the JWT_VERIFY_EXPIRATION setting.

Authentication in GraphQL queries

Now in order to access protected API you must include the Authorization: JWT <token> header.

Django-graphql-jwt uses middleware to hook the authenticated user into request object. The simple, raw way to limit access to data is to check info.context.user.is_authenticated:

import graphene


class Query(graphene.ObjectType):
    viewer = graphene.Field(UserType)

    def resolve_viewer(self, info, **kwargs):
        user = info.context.user
        if not user.is_authenticated:
            raise Exception('Authentication credentials were not provided')
        return user

As a shortcut, you can use the login_required() decorator for your resolvers and mutations:

See the documentation for the full list of decorators.

import graphene
from graphql_jwt.decorators import login_required


class Query(graphene.ObjectType):
    viewer = graphene.Field(UserType)

    @login_required
    def resolve_viewer(self, info, **kwargs):
        return info.context.user

Relay

Complete support for Relay.

import graphene
import graphql_jwt


class Mutations(graphene.ObjectType):
    token_auth = graphql_jwt.relay.ObtainJSONWebToken.Field()
    verify_token = graphql_jwt.relay.Verify.Field()
    refresh_token = graphql_jwt.relay.Refresh.Field()

Relay mutations only accepts one argument named input, read the documentation for more info.

Customizing

If you want to customize the ObtainJSONWebToken behavior, you’ll need to customize the resolve() method on a subclass of JSONWebTokenMutation or .relay.JSONWebTokenMutation.

import graphene
import graphql_jwt


class ObtainJSONWebToken(graphql_jwt.JSONWebTokenMutation):
    user = graphene.Field(UserType)

    @classmethod
    def resolve(cls, root, info):
        return cls(user=info.context.user)

Authenticate the user and obtain the token and the user id.

mutation TokenAuth($username: String!, $password: String!) {
  tokenAuth(username: $username, password: $password) {
    token
    user {
      id
    }
  }
}

Writing tests

This package includes a subclass of unittest.TestCase and improve support for making GraphQL queries using JSON Web Token authentication.

from django.contrib.auth import get_user_model

from graphql_jwt.testcases import JSONWebTokenTestCase


class UsersTests(JSONWebTokenTestCase):

    def setUp(self):
        self.user = get_user_model().objects.create(username='test')
        self.client.authenticate(self.user)

    def test_get_user(self):
        query = '''
        query GetUser($username: String!) {
          user(username: $username) {
            id
          }
        }'''
        self.client.execute(query, variables={'username': self.user.username})

Settings

Django-graphql-jwt reads your configuration from a single Django setting named GRAPHQL_JWT

GRAPHQL_JWT = {
    'JWT_VERIFY_EXPIRATION': True,
    'JWT_EXPIRATION_DELTA': timedelta(minutes=10),
}

Here’s a list of settings available in Django-graphql-jwt and their default values.

JWT_ALGORITHM

Algorithm for cryptographic signing
Default: 'HS256'

JWT_AUDIENCE

Identifies the recipients that the JWT is intended for
Default: None

JWT_ISSUER

Identifies the principal that issued the JWT
Default: None

JWT_LEEWAY

Validate an expiration time which is in the past but not very far
Default: timedelta(seconds=0)

JWT_SECRET_KEY

The secret key used to sign the JWT
Default: settings.SECRET_KEY

JWT_VERIFY

Secret key verification
Default: True

JWT_VERIFY_EXPIRATION

Expiration time verification
Default: False

JWT_EXPIRATION_DELTA

Timedelta added to utcnow() to set the expiration time
Default: timedelta(minutes=5)

JWT_ALLOW_REFRESH

Enable token refresh
Default: True

JWT_REFRESH_EXPIRATION_DELTA

Limit on token refresh
Default: timedelta(days=7)

JWT_LONG_RUNNING_REFRESH_TOKEN

Enable long time running refresh token
Default: False

JWT_REFRESH_TOKEN_MODEL

The model to use to represent a refresh token
Default: 'refresh_token.RefreshToken'

JWT_REFRESH_TOKEN_N_BYTES

Refresh token number of bytes
Default: 20

JWT_AUTH_HEADER

Authorization header name
Default: 'HTTP_AUTHORIZATION'

JWT_AUTH_HEADER_PREFIX

Authorization prefix
Default: 'JWT'

JWT_ENCODE_HANDLER

A custom function `f(payload, context)` to encode the token
Default: 'graphql_jwt.utils.jwt_encode'

JWT_DECODE_HANDLER

A custom function `f(token, context)` to decode the token
Default: 'graphql_jwt.utils.jwt_decode'

JWT_PAYLOAD_HANDLER

A custom function `f(user, context)` to generate the token payload
Default: 'graphql_jwt.utils.jwt_payload'

JWT_PAYLOAD_GET_USERNAME_HANDLER

A custom function `f(payload)` to obtain the username
Default: lambda payload: payload.get(get_user_model().USERNAME_FIELD)

JWT_REFRESH_EXPIRED_HANDLER

A custom function `f(orig_iat, context)` to determine if refresh has expired
Default: 'graphql_jwt.utils.refresh_has_expired'

Credits and thanks.

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

django-graphql-jwt-0.1.14.tar.gz (18.0 kB view details)

Uploaded Source

Built Distribution

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

django_graphql_jwt-0.1.14-py2.py3-none-any.whl (26.4 kB view details)

Uploaded Python 2Python 3

File details

Details for the file django-graphql-jwt-0.1.14.tar.gz.

File metadata

  • Download URL: django-graphql-jwt-0.1.14.tar.gz
  • Upload date:
  • Size: 18.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Python-urllib/3.6

File hashes

Hashes for django-graphql-jwt-0.1.14.tar.gz
Algorithm Hash digest
SHA256 56168bc2f85283fbe6569357051c7d5ea4acb0ef0d56436e3f01dde9bf7c9b4e
MD5 4c2b24ac35f4ba64a39dae0d7ebd63de
BLAKE2b-256 659527bb7ed128bc362e9efbb5976d54e974c783d172637d72148a532b3434be

See more details on using hashes here.

File details

Details for the file django_graphql_jwt-0.1.14-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for django_graphql_jwt-0.1.14-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 690683a9f619b8c785f0297aa7e6ea7a047877b59b3417d550591899a119e58e
MD5 df98fb9ff2f5ab1583977a91bc387aee
BLAKE2b-256 a2603d2d5c3d2045da1417b0d33f8d7ae8d01ea7da56bb3c4f9d67a59454d1b9

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