Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GraphQL explorer disabled by this library #245

Closed
Lucasmiguelmac opened this issue Mar 5, 2022 · 4 comments
Closed

GraphQL explorer disabled by this library #245

Lucasmiguelmac opened this issue Mar 5, 2022 · 4 comments

Comments

@Lucasmiguelmac
Copy link

Lucasmiguelmac commented Mar 5, 2022

When I setup this library, my GraphQL explorer is no longer able to introspect my backend's schema.

The problem stops if I comment JSONWebTokenMiddleware in my schema's extensions:

schema = strawberry.Schema(
    query=Query,
    mutation=Mutation,
    extensions=[
        ...
        JSONWebTokenMiddleware # -> Comment this and in starts working again
        ...
    ],
)

It does work nonetheless:
image
It seems like the explorer is suddenly not obtaining something it's looking for:
image

This is my setup:

# settings.py
import os
from pathlib import Path


BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = os.environ.get("SECRET_KEY")

DEBUG = os.environ.get("DEBUG")

ALLOWED_HOSTS = [el for el in os.environ.get("ALLOWED_HOSTS").split(",")]

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    # Project apps
    "users",
    # Third party apps
    "corsheaders",
    "strawberry_django_jwt.refresh_token"
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware"
]

ROOT_URLCONF = "project.urls"

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    },
]

WSGI_APPLICATION = "project.wsgi.application"

DATABASES = {
    "default": {
        "ENGINE": os.environ.get("SQL_ENGINE"),
        "NAME": os.environ.get("SQL_DATABASE"),
        "USER": os.environ.get("SQL_USER"),
        "PASSWORD": os.environ.get("SQL_PASSWORD"),
        "HOST": os.environ.get("SQL_HOST"),
        "PORT": os.environ.get("SQL_PORT"),
    }
}

AUTH_PASSWORD_VALIDATORS = [
    {
        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
    },
]

LANGUAGE_CODE = "en-us"

TIME_ZONE = "UTC"

USE_I18N = True

USE_L10N = True

USE_TZ = True

STATIC_URL = "/static/"

AUTH_USER_MODEL = "users.CustomUser"

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

AUTHENTICATION_BACKENDS = [
    'strawberry_django_jwt.backends.JSONWebTokenBackend',
    'django.contrib.auth.backends.ModelBackend',
]
GRAPHQL_JWT = {"JWT_AUTHENTICATE_INTROSPECTION": True}
# urls.py
from django.conf import settings
from django.contrib import admin
from django.urls import path
from strawberry.django.views import GraphQLView

from project.schema import schema


if settings.DEBUG:
    urlpatterns = [
        path("admin/", admin.site.urls),
        path("graphql/", GraphQLView.as_view(schema=schema)),
    ]
else:
    urlpatterns = [
        # Safe urls grabbed from .env
    ]
# from typing import List
import strawberry
from strawberry_django_jwt.middleware import JSONWebTokenMiddleware
from strawberry_django_plus import directives, optimizer
from users.api import types as ut, resolvers as ur, permissions as up
import strawberry_django_jwt.mutations as jwt_mutations


@strawberry.type
class Query:
    me: ut.User = strawberry.field(
        resolver=ur.me,
        permission_classes=[up.IsAuthenticated]
    )


@strawberry.type
class Mutation:
    create_user:    ut.User         = strawberry.mutation(resolver=ur.create_user)
    login_user:     ut.LoginSuccess = strawberry.mutation(resolver=ur.login)
    logout_user:    ut.User         = strawberry.mutation(resolver=ur.logout)
    token_auth = jwt_mutations.ObtainJSONWebToken.obtain
    verify_token = jwt_mutations.Verify.verify
    refresh_token = jwt_mutations.Refresh.refresh
    delete_token_cookie = jwt_mutations.DeleteJSONWebTokenCookie.delete_cookie

schema = strawberry.Schema(
    query=Query,
    mutation=Mutation,
    extensions=[
        optimizer.DjangoOptimizerExtension,
        directives.SchemaDirectiveExtension,
        JSONWebTokenMiddleware
    ],
)
# resolvers.py
from typing import Union
from strawberry.types import Info
from strawberry_django import django_resolver
from django.contrib import auth

from project.common.utils import data_to_dict
from users import models as m
from users.api import types as t


def create_user(self, info: Info, data: t.UserInput) -> t.User:
    user_data = data_to_dict(data)
    user = m.CustomUser(**user_data)
    user.set_password(data.password)
    user.save()
    return user

def login(self, info: Info, data: t.UserInput) -> t.LoginResult:
    request = info.context.request

    user = auth.authenticate(
        request=request,
        email=data.email,
        password=data.password
    )

    if user is not None:
        auth.login(request, user)
        return t.LoginSuccess(user=user)
    auth.logout(request)
    return t.LoginError(message="Credenciales erróneas")

def logout(self, info: Info) -> bool:
    request = info.context.request
    ret = request.user.is_authenticated
    auth.logout(request)
    return ret

def me(self, info: Info) -> t.User | None:
    user: m.CustomUser = info.context.request.user
    if user.is_authenticated:
        return user
    return None
@ashishnitinpatil
Copy link

I think it's because you have GRAPHQL_JWT = {"JWT_AUTHENTICATE_INTROSPECTION": True} and you have not logged in.

@Lucasmiguelmac
Copy link
Author

I think it's because you have GRAPHQL_JWT = {"JWT_AUTHENTICATE_INTROSPECTION": True} and you have not logged in.

Yep, I closed it and forgot to put my answer. I set it to DEBUG

@sanginovs
Copy link

Hey @ashishnitinpatil @Lucasmiguelmac @KundaPanda
Running into the same issue.
I added GRAPHQL_JWT = {"JWT_AUTHENTICATE_INTROSPECTION": True} to settings.py.
The mutation work though but i am getting No schema available because The introspection query requires authentication.

How do i authenticate introspection query ?
Isn't adding this line enough for it to work?
GRAPHQL_JWT = {"JWT_AUTHENTICATE_INTROSPECTION": True}

@sanginovs
Copy link

sanginovs commented Aug 28, 2022

ok never mind.
Just setting the flag to False removed this auth requirement:
GRAPHQL_JWT = {"JWT_AUTHENTICATE_INTROSPECTION": False}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants