flavors / django-graphql-jwt

JSON Web Token (JWT) authentication for Graphene Django
https://django-graphql-jwt.domake.io
MIT License
820 stars 173 forks source link

Token verification is not working, no error reported #245

Open alejandrodp opened 3 years ago

alejandrodp commented 3 years ago

Problem

When I try to verify a token, graphene throws the unauthenticated user error, that is in the schema, but django-graphql-jwt doesn't show any error. I am missing something or there is a bug?

I am using these versions of the lib and its depndencies:

Django==3.1.5 graphene-django==2.15.0 graphene==2.1.8 PyJWT==1.7.1

Configuration

GRAPHENE = {
    'SCHEMA': 'app.schema.schema',
    'MIDDLEWARE': [
        'graphql_jwt.middleware.JSONWebTokenMiddleware',
    ],
}

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

GRAPHQL_JWT = {
    'JWT_VERIFY_EXPIRATION': False,
    'JWT_EXPIRATION_DELTA': timedelta(minutes=10),
    'JWT_ALGORITHM': 'RS256',
    'JWT_ISSUER': COGNITO_ISSUER,
    'JWT_DECODE_HANDLER': validate_cognito_token,
    'JWT_VERIFY': True
}

Function that I use to decode the tokens (because the default method not work with this tokens). Taken from here: https://github.com/jpadilla/pyjwt/issues/359#issuecomment-456608816

import json
import jwt
import requests
from jwt.algorithms import RSAAlgorithm

def validate_cognito_token(id_token, cognito_region, cognito_user_pool_id, cognito_app_client_id):
    jwks = requests.get('https://cognito-idp.{aws_region}.amazonaws.com/{user_pool_id}/.well-known/jwks.json'.format(aws_region=cognito_region, user_pool_id=cognito_user_pool_id)).json()
    keys = {k['kid']: RSAAlgorithm.from_jwk(json.dumps(k)) for k in jwks['keys']}
    header = jwt.get_unverified_header(id_token)
    key_id = header['kid']
    algorithm = header['alg']
    pub_key = keys[key_id]
    # Next line raises errors if the audience isn't right or if the token is expired or has other errors.
    valid_token_data = jwt.decode(id_token, pub_key, audience=cognito_app_client_id, algorithm=algorithm)
    return valid_token_data

Schema

import graphene
import graphql_jwt

class Query(graphene.ObjectType):
    hello = graphene.String()

    def resolve_hello(root, info):
        user = info.context.user
        if not user.is_authenticated:
            raise Exception('Authentication credentials were not provided')
        return "Hello"

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

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

urls.py

from django.urls import path
from graphene_django.views import GraphQLView

urlpatterns = [
    path("graphql", GraphQLView.as_view(graphiql=True)),
]

Error when using graphql endpoint

Traceback (most recent call last):
  File ".../virtualenv/project/lib/python3.9/site-packages/promise/promise.py", line 489, in _resolve_from_executor
    executor(resolve, reject)
  File ".../virtualenv/project/lib/python3.9/site-packages/promise/promise.py", line 756, in executor
    return resolve(f(*args, **kwargs))
  File ".../virtualenv/project/lib/python3.9/site-packages/graphql/execution/middleware.py", line 75, in make_it_promise
    return next(*args, **kwargs)
  File ".../virtualenv/project/app/schema.py", line 10, in resolve_hello
    raise Exception('Authentication credentials were not provided')
graphql.error.located_error.GraphQLLocatedError: Authentication credentials were not provided
mikedizon commented 2 years ago

@alejandrodp were you able to resolve this? i don't think the function gets triggered

alejandrodp commented 2 years ago

@mikedizon Actually, I gave up with this library and made my own middleware to process the tokens using cognitojwt. It was a better and simpler solution. Also probably I missed out some configuration that was preventing the function to get triggered like you points out. But if anyone has the same problem, I hope this issue can help for reference.

mikedizon commented 2 years ago

@alejandrodp thanks, i'll have a look at your project. i'm authenticating with auth0. hopefully there's some overlap