JSON Web Token for Django GraphQL
Project description
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 obtain a brand new token with renewed expiration time for non-expired tokens.
Configure your refresh token scenario and set the flag JWT_VERIFY_EXPIRATION=true.
mutation RefreshToken($token: String!) {
refreshToken(token: $token) {
token
payload
}
}
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_users(self):
query = '''
query GetUsers($username: String) {
users(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_EXPIRATION_DELTA': timedelta(minutes=10),
}
Here’s a list of settings available in Django-graphql-jwt and their default values.
Algorithm for cryptographic signing Default: 'HS256'
Identifies the recipients that the JWT is intended for Default: None
Identifies the principal that issued the JWT Default: None
Validate an expiration time which is in the past but not very far Default: timedelta(seconds=0)
The secret key used to sign the JWT Default: settings.SECRET_KEY
Secret key verification Default: True
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_AUTH_HEADER
Authorization header name Default: 'HTTP_AUTHORIZATION'
JWT_AUTH_HEADER_PREFIX
Authorization prefix Default: 'JWT'
JWT_PAYLOAD_HANDLER
A custom function `f(user, context)` to generate the token payload Default: 'graphql_jwt.utils.jwt_payload'
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_GET_USERNAME_HANDLER
A custom function `f(payload)` to obtain the username Default: lambda payload: payload.get(get_user_model().USERNAME_FIELD)
Credits and thanks.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django-graphql-jwt-0.1.13.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | f00a135baef6729b5816b32ea97f0fd49925d16e07054013139938295f1d5e66 |
|
MD5 | ad6da634ee8f764a60248b307db1f3dd |
|
BLAKE2b-256 | f5a2951a071796f5031bb48e3a81bb90436faae95e9f94418b14ec5a2e63c008 |
Hashes for django_graphql_jwt-0.1.13-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 619e76d3eabd05732f3e267ddb6d60e5e63a119002f91b316de26cdf66699d25 |
|
MD5 | 82dce77376b13113362838795967d393 |
|
BLAKE2b-256 | b0c1e902ab58547cbaa0bc2d17135589949bbbd62a3a640243da5c875ff3ea4f |