Not sure if the best place for this issue is here or at graphene repo (https://github.com/graphql-python/graphene), but here we go ...
I have a Node.Field that I want to match to a resolver in order to apply token authentication/authorization. But it seems the resolver is completely ignored. Here is a code sample:
from graphene_django.types import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from graphene import ObjectType, Node, String
from core.utils import validate_token
from .models import Paciente
class PacienteType(DjangoObjectType):
class Meta:
model = Paciente
interfaces = (Node, )
filter_fields = ['id', 'nome']
class Query(ObjectType):
paciente = Node.Field(PacienteType, id=String(), token=String())
paciente_all = DjangoFilterConnectionField(PacienteType, token=String())
def resolve_paciente(self, info, id=None, token=None):
usuario_id = validate_token(token)
if usuario_id is None:
return None
try:
return Paciente.objects.get(pk=id)
except:
return None
def resolve_paciente_all(self, info, token=None):
usuario_id = validate_token(token)
if usuario_id is None:
return []
return Paciente.objects.all()
Then I issue the following query
{
paciente(id: "UGFjaWVudGVUeXBlOjE=") {
id
}
}
Which I expected to be blank, since I'm not supplying any auth token, but it does return with one result. Am I missing something here that I have not seem, or this may be a bug?
Thanks!
can you try printing in resolve_paciente to see if it is being ran?
I did place a pdb.set_trace() (python's debugger), and in fact it wasn't being called/stopped at all.
Try this, instead of:
paciente = Node.Field(PacienteType, id=String(), token=String())
do:
paciente = graphene.Field(PacienteType, id=String(), token=String())
or simply:
paciente = graphene.Field(PacienteType)
The documentation is non existent, and examples are very inconsistent, lack descriptions, lack the "why's", versions mixed, relay vs non-relay confused, etc. Looks like nobody is really in charge of this project so get ready for trial and error unfortunately.
to resolve a global id, inside a normal field do
relay.Node.get_node_from_global_id(info, id)
@vinigfer
If you want to implement something like token authentication, you probably want it outside of each individual resolver. I would suggest subclassing GraphQLView with django's LoginRequiredMixin (as seen here, and then adding the token authentication as one of your django authentication methods.
Some time passed however i had the same kind of problem and have found kind of solution.
Everything works fine while resolving DjangoFilterConnectionField. In cases of graphene.relay.Node.Field, resolver as vingifer said above is being ignored.
What I have done to work with it is: changing graphene.relay.Node.Field back to graphene.Field (no relay format). Resolver works, I just needed to work inside about understanding the relay format ID.
If somone has better solution I would appreciate as well. We all here know that some complications around graphene and relay exist ;)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
to resolve a global id, inside a normal field do
relay.Node.get_node_from_global_id(info, id)
I wish I knew how this worked, really is like magic to me
Most helpful comment
Try this, instead of:
paciente = Node.Field(PacienteType, id=String(), token=String())do:
paciente = graphene.Field(PacienteType, id=String(), token=String())or simply:
paciente = graphene.Field(PacienteType)The documentation is non existent, and examples are very inconsistent, lack descriptions, lack the "why's", versions mixed, relay vs non-relay confused, etc. Looks like nobody is really in charge of this project so get ready for trial and error unfortunately.