{"id":20477869,"url":"https://github.com/usama0121/ariadne-jwt","last_synced_at":"2025-04-13T13:12:59.492Z","repository":{"id":41240091,"uuid":"286032277","full_name":"Usama0121/ariadne-jwt","owner":"Usama0121","description":"JSON Web Token (JWT) authentication for Ariadne Django","archived":false,"fork":false,"pushed_at":"2022-11-10T09:26:50.000Z","size":93,"stargazers_count":29,"open_issues_count":7,"forks_count":15,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-13T05:03:59.715Z","etag":null,"topics":["ariadne","django","graphql","jwt","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Usama0121.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"custom":["https://www.buymeacoffee.com/muhammad.usama"]}},"created_at":"2020-08-08T11:42:21.000Z","updated_at":"2024-11-07T09:54:56.000Z","dependencies_parsed_at":"2023-01-22T10:15:55.969Z","dependency_job_id":null,"html_url":"https://github.com/Usama0121/ariadne-jwt","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Usama0121%2Fariadne-jwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Usama0121%2Fariadne-jwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Usama0121%2Fariadne-jwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Usama0121%2Fariadne-jwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Usama0121","download_url":"https://codeload.github.com/Usama0121/ariadne-jwt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248717237,"owners_count":21150389,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ariadne","django","graphql","jwt","python"],"created_at":"2024-11-15T15:33:58.209Z","updated_at":"2025-04-13T13:12:59.468Z","avatar_url":"https://github.com/Usama0121.png","language":"Python","funding_links":["https://www.buymeacoffee.com/muhammad.usama"],"categories":[],"sub_categories":[],"readme":"# Ariadne JWT\n\nJSON Web Token for Ariadne Django\n\n## Installation\n\n~~~shell\npip install ariadne-jwt\n~~~\n\nInclude the `JSONWebTokenMiddleware` in your *MIDDLEWARE* settings:\n\n~~~python\nMIDDLEWARE = [\n    'django.contrib.auth.middleware.AuthenticationMiddleware',\n    'ariadne_jwt.middleware.JSONWebTokenMiddleware',\n]\n~~~\n\nInclude the `JSONWebTokenBackend` in your *AUTHENTICATION_BACKENDS* settings:\n\n~~~python\nAUTHENTICATION_BACKENDS = [\n    'ariadne_jwt.backends.JSONWebTokenBackend',\n    'django.contrib.auth.backends.ModelBackend'\n]\n~~~\n\n## Schema\n\nAdd mutations to your GraphQL schema\n\n~~~python\nimport ariadne\nfrom ariadne_jwt import resolve_verify, resolve_refresh, resolve_token_auth, jwt_schema, GenericScalar\n\ntype_defs = '''\n    type Mutation {\n        ...\n        verifyToken(token: String!): VerifyToken\n        refreshToken(token: String!): RefreshToken\n        tokenAuth(username: String!, password:String!): TokenAuth\n        ...\n    }\n    '''\n\nmutation = ariadne.MutationType()\n\nmutation.set_field('verifyToken', resolve_verify)\nmutation.set_field('refreshToken', resolve_refresh)\nmutation.set_field('tokenAuth', resolve_token_auth)\n\nschema = ariadne.make_executable_schema([type_defs, jwt_schema], mutation, GenericScalar)\n~~~\n\n- `tokenAuth` to authenticate the user and obtain the JSON Web Token.\n\nThe resolver uses User's model `USERNAME_FIELD`_, which by default is ``username``.\n\n~~~graphql\nmutation TokenAuth($username: String!, $password: String!) {\n    tokenAuth(username: $username, password: $password) {\n        token\n    }\n}\n~~~\n\n- `verifyToken` to confirm that the token is valid.\n\n~~~graphql\nmutation VerifyToken($token:String!) {\n    verifyToken(token: $token) {\n        payload\n    }\n}\n~~~\n\n- `refreshToken` to obtain a brand new *token* with renewed expiration time for non-expired tokens.\n\n~~~graphql\nmutation RefreshToken($token: String!) {\n    refreshToken(token: $token) {\n        token\n        payload\n    }\n}\n~~~\n\n## Authentication in GraphQL queries\n\nNow in order to access protected API you must include the ``Authorization: JWT \u003ctoken\u003e`` header. you can use\nthe ``login_required()`` decorator for your *resolvers*:\n\n~~~python\nfrom ariadne import QueryType\nfrom ariadne_jwt.decorators import login_required\n\ntype_defs = '''\ntype UserNode {\n    username:String\n    email: String\n}\ntype Query {\n    me: UserNode\n}\n'''\n\nquery = QueryType()\n\n\n@query.field('me')\n@login_required\ndef resolve_viewer(self, info, **kwargs):\n    return info.context.get('request').user\n~~~\n\n## Customizing\n\nIf you want to customize the ``tokenAuth`` behavior, you'll need to extend the ``TokenAuth`` type and write a resolver\nwith @token_auth decorator.\n\n~~~python\nfrom ariadne_jwt.decorators import token_auth\n\nextended_type_defs = '''\ntype UserNode {\n    id\n    username\n    email\n}\nextend type TokenAuth {\n    user: UserNode\n}\n'''\n\n\n@token_auth\ndef resolve_token_auth(obj, info, **kwargs):\n    return {'user': info.context.get('request').user}\n~~~\n\n~~~graphql\nmutation TokenAuth($username: String!, $password: String!) {\n    tokenAuth(username: $username, password: $password) {\n        token\n        user {\n            id\n        }\n    }\n}\n~~~\n\n## Settings\n\n*ariadne-jwt* reads your configuration from a single **Django setting** named ``GRAPHQL_JWT``\n\n~~~python\nGRAPHQL_JWT = {\n    'JWT_VERIFY_EXPIRATION': True,\n    'JWT_EXPIRATION_DELTA': timedelta(seconds=60 * 10)\n}\n~~~\n\n### Default Settings\n\n~~~python\nDEFAULTS = {\n    # Algorithm for cryptographic signing\n    'JWT_ALGORITHM': 'HS256',\n\n    # Identifies the recipients that the JWT is intended for\n    'JWT_AUDIENCE': None,\n\n    # Identifies the principal that issued the JWT\n    'JWT_ISSUER': None,\n\n    # Validate an expiration time which is in the past but not very far\n    'JWT_LEEWAY': 0,\n\n    # The secret key used to sign the JWT\n    'JWT_SECRET_KEY': settings.SECRET_KEY,\n\n    # Secret key verification\n    'JWT_VERIFY': True,\n\n    # Expiration time verification\n    'JWT_VERIFY_EXPIRATION': False,\n\n    # Timedelta added to utcnow() to set the expiration time\n    'JWT_EXPIRATION_DELTA': timedelta(seconds=60 * 5),\n\n    # Enable token refresh\n    'JWT_ALLOW_REFRESH': True,\n\n    # Limit on token refresh\n    'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=7),\n\n    # Enable long time running refresh token\n    'JWT_LONG_RUNNING_REFRESH_TOKEN': False,\n\n    # The model to use to represent a refresh token\n    'JWT_REFRESH_TOKEN_MODEL': 'refresh_token.RefreshToken',\n\n    # Refresh token number of bytes\n    'JWT_REFRESH_TOKEN_N_BYTES': 20,\n\n    # Authorization header name\n    'JWT_AUTH_HEADER': 'HTTP_AUTHORIZATION',\n\n    # Authorization prefix\n    'JWT_AUTH_HEADER_PREFIX': 'JWT',\n\n    # A custom function *f(payload, context)* to encode the token\n    'JWT_ENCODE_HANDLER': 'ariadne_jwt.utils.jwt_encode',\n\n    # A custom function *f(token, context)* to decode the token\n    'JWT_DECODE_HANDLER': 'ariadne_jwt.utils.jwt_decode',\n\n    # A custom function *f(user, context)* to generate the token payload\n    'JWT_PAYLOAD_HANDLER': 'ariadne_jwt.utils.jwt_payload',\n\n    # A custom function `f(payload)` to obtain the username    \n    'JWT_PAYLOAD_GET_USERNAME_HANDLER': (lambda payload: payload.get(get_user_model().USERNAME_FIELD)),\n\n    # A custom function `f(orig_iat, context)` to determine if refresh has expired\n    'JWT_REFRESH_EXPIRED_HANDLER': 'ariadne_jwt.utils.refresh_has_expired',\n}\n~~~\n\n# Writing tests\n\n~~~python\nfrom django.contrib.auth import get_user_model\nfrom ariadne_jwt.testcases import JSONWebTokenTestCase\n\n\nclass UserTests(JSONWebTokenTestCase):\n    def setUp(self):\n        self.user = get_user_model().objects.create_user(username='test', password='dolphins')\n        self.client.authenticate(self.user)\n        self.client.schema(type_defs, resolvers, directives=directives)\n\n    def test_get_user(self):\n        query = '''\n            query GetUser($username: String) {\n                user(username: $username) {\n                    id\n                }\n            }\n            '''\n        self.client.execute(query, variables={'username': self.user.username})\n~~~\n\n# Testing the library\n\nrun the following in root directory\n\n~~~shell script\npython run_tests.py\n~~~","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fusama0121%2Fariadne-jwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fusama0121%2Fariadne-jwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fusama0121%2Fariadne-jwt/lists"}