JSON Web Token for Ariadne Django
Project description
Ariadne JWT
JSON Web Token for Ariadne Django
Installation
pip install ariadne-jwt
Include the JSONWebTokenMiddleware
in your MIDDLEWARE settings:
MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware',
'ariadne_jwt.middleware.JSONWebTokenMiddleware',
]
Include the JSONWebTokenBackend
in your AUTHENTICATION_BACKENDS settings:
AUTHENTICATION_BACKENDS = [
'ariadne_jwt.backends.JSONWebTokenBackend',
'django.contrib.auth.backends.ModelBackend'
]
Schema
Add mutations to your GraphQL schema
import ariadne
from ariadne_jwt import resolve_verify, resolve_refresh, resolve_token_auth, jwt_schema, GenericScalar
type_defs = '''
type Mutation {
...
verifyToken(token: String!): VerifyToken
refreshToken(token: String!): RefreshToken
tokenAuth(username: String!, password:String!): TokenAuth
...
}
'''
mutation = ariadne.MutationType()
mutation.set_field('verifyToken', resolve_verify)
mutation.set_field('refreshToken', resolve_refresh)
mutation.set_field('tokenAuth', resolve_token_auth)
schema = ariadne.make_executable_schema([type_defs, jwt_schema], mutation, GenericScalar)
tokenAuth
to authenticate the user and obtain the JSON Web Token.
The resolver uses 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.
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. you can use
the login_required()
decorator for your resolvers:
from ariadne import QueryType
from ariadne_jwt.decorators import login_required
type_defs = '''
type UserNode {
username:String
email: String
}
type Query {
me: UserNode
}
'''
query = QueryType()
@query.field('me')
@login_required
def resolve_viewer(self, info, **kwargs):
return info.context.get('request').user
Customizing
If you want to customize the tokenAuth
behavior, you'll need to extend the TokenAuth
type and write a resolver
with @token_auth decorator.
from ariadne_jwt.decorators import token_auth
extended_type_defs = '''
type UserNode {
id
username
email
}
extend type TokenAuth {
user: UserNode
}
'''
@token_auth
def resolve_token_auth(obj, info, **kwargs):
return {'user': info.context.get('request').user}
mutation TokenAuth($username: String!, $password: String!) {
tokenAuth(username: $username, password: $password) {
token
user {
id
}
}
}
Settings
ariadne-jwt reads your configuration from a single Django setting named GRAPHQL_JWT
GRAPHQL_JWT = {
'JWT_VERIFY_EXPIRATION': True,
'JWT_EXPIRATION_DELTA': timedelta(seconds=60 * 10)
}
Default Settings
DEFAULTS = {
# Algorithm for cryptographic signing
'JWT_ALGORITHM': 'HS256',
# Identifies the recipients that the JWT is intended for
'JWT_AUDIENCE': None,
# Identifies the principal that issued the JWT
'JWT_ISSUER': None,
# Validate an expiration time which is in the past but not very far
'JWT_LEEWAY': 0,
# The secret key used to sign the JWT
'JWT_SECRET_KEY': settings.SECRET_KEY,
# Secret key verification
'JWT_VERIFY': True,
# Expiration time verification
'JWT_VERIFY_EXPIRATION': False,
# Timedelta added to utcnow() to set the expiration time
'JWT_EXPIRATION_DELTA': timedelta(seconds=60 * 5),
# Enable token refresh
'JWT_ALLOW_REFRESH': True,
# Limit on token refresh
'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=7),
# Enable long time running refresh token
'JWT_LONG_RUNNING_REFRESH_TOKEN': False,
# The model to use to represent a refresh token
'JWT_REFRESH_TOKEN_MODEL': 'refresh_token.RefreshToken',
# Refresh token number of bytes
'JWT_REFRESH_TOKEN_N_BYTES': 20,
# Authorization header name
'JWT_AUTH_HEADER': 'HTTP_AUTHORIZATION',
# Authorization prefix
'JWT_AUTH_HEADER_PREFIX': 'JWT',
# A custom function *f(payload, context)* to encode the token
'JWT_ENCODE_HANDLER': 'ariadne_jwt.utils.jwt_encode',
# A custom function *f(token, context)* to decode the token
'JWT_DECODE_HANDLER': 'ariadne_jwt.utils.jwt_decode',
# A custom function *f(user, context)* to generate the token payload
'JWT_PAYLOAD_HANDLER': 'ariadne_jwt.utils.jwt_payload',
# A custom function `f(payload)` to obtain the username
'JWT_PAYLOAD_GET_USERNAME_HANDLER': (lambda payload: payload.get(get_user_model().USERNAME_FIELD)),
# A custom function `f(orig_iat, context)` to determine if refresh has expired
'JWT_REFRESH_EXPIRED_HANDLER': 'ariadne_jwt.utils.refresh_has_expired',
}
Writing tests
from django.contrib.auth import get_user_model
from ariadne_jwt.testcases import JSONWebTokenTestCase
class UserTests(JSONWebTokenTestCase):
def setUp(self):
self.user = get_user_model().objects.create_user(username='test', password='dolphins')
self.client.authenticate(self.user)
self.client.schema(type_defs, resolvers, directives=directives)
def test_get_user(self):
query = '''
query GetUser($username: String) {
user(username: $username) {
id
}
}
'''
self.client.execute(query, variables={'username': self.user.username})
Testing the library
run the following in root directory
python run_tests.py
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
Built Distribution
File details
Details for the file ariadne-jwt-0.1.7.tar.gz
.
File metadata
- Download URL: ariadne-jwt-0.1.7.tar.gz
- Upload date:
- Size: 14.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.1.post20200807 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.7.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4e5082af612fc4995f0771b3e26e380210979c8401b6a882903c96d4d41a8492 |
|
MD5 | 3e2ea147b262b8b34be7ab76d293f33d |
|
BLAKE2b-256 | 21bde4a1c88880e441bce18068eb920b7552185150f6b7c7ebbd57ba58ad4214 |
File details
Details for the file ariadne_jwt-0.1.7-py2.py3-none-any.whl
.
File metadata
- Download URL: ariadne_jwt-0.1.7-py2.py3-none-any.whl
- Upload date:
- Size: 19.0 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.1.post20200807 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.7.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4aa42050bf5b9d3b6394e867cfbc288d831596d2fe6db17e39aaff4a7fb9cf10 |
|
MD5 | b991bc138c157abfe72b9c20dc4c9382 |
|
BLAKE2b-256 | c8cd44273777235d7afe51c8e868eb9e770c43c2755bcd64053869ee697b35d1 |