IndominusByte / fastapi-jwt-auth

FastAPI extension that provides JWT Auth support (secure, easy to use, and lightweight)
http://indominusbyte.github.io/fastapi-jwt-auth/
MIT License
644 stars 150 forks source link

How can I use it in graphql? #28

Closed amiyatulu closed 3 years ago

amiyatulu commented 3 years ago

Is it possible to use it in graphql? https://fastapi.tiangolo.com/advanced/graphql/

Tried this: https://github.com/tiangolo/fastapi/issues/1279

But it's not showing the graphiql ide : {"detail":"Method Not Allowed"}

IndominusByte commented 3 years ago

method not allowed because graphQLFetcher fetch with the same path as graphiql which only supports the get method, I saw from starlette graphql source code

Screen Shot 2020-12-07 at 12 09 57 Screen Shot 2020-12-07 at 12 10 41

to pass fastapi dependencies you can do this

import graphene
from fastapi import FastAPI, Request, Depends
from fastapi_jwt_auth import AuthJWT
from starlette.graphql import GraphQLApp
from starlette.datastructures import URL
from pydantic import BaseModel

class Settings(BaseModel):
    authjwt_secret_key: str = "secret"

@AuthJWT.load_config
def get_config():
    return Settings()

class Query(graphene.ObjectType):
    hello = graphene.String(name=graphene.String(default_value="stranger"))

    def resolve_hello(self, info, name):
        authorize = info.context['request'].state.authorize
        access_token = authorize.create_access_token(subject=name)
        return "Hello " + name + "access_token" + access_token

app = FastAPI()
graphql_app = GraphQLApp(schema=graphene.Schema(query=Query))

@app.get('/')
async def graphiql(request: Request):
    request._url = URL('/gql')
    return await graphql_app.handle_graphiql(request=request)

@app.post('/gql')
async def graphql(request: Request, authorize: AuthJWT = Depends()):
    request.state.authorize = authorize
    return await graphql_app.handle_graphql(request=request)

I'm sorry if my explanation is bad cause I never use graphql, I hope this can answer your question 😄

amiyatulu commented 3 years ago

Thank you. Its working.

IndominusByte commented 3 years ago

Glad to hear that 😄 🙏

matthewchung74 commented 3 years ago

hi @IndominusByte , was wondering if I could get your 2 cents? I modified the above example for database connections.

import fastapi
import uvicorn

import graphene
from fastapi import FastAPI, Request, Depends
from starlette.graphql import GraphQLApp
from starlette.datastructures import URL
from pydantic import BaseModel

from app.api import deps
from sqlalchemy.orm import Session

app = fastapi.FastAPI()

class Query(graphene.ObjectType):
    hello = graphene.String(name=graphene.String(default_value="stranger"))

    def resolve_hello(self, info, name):
        db = info.context['request'].state.db
        return f"hi {name}, db active {db.is_active}"

app = FastAPI()
graphql_app = GraphQLApp(schema=graphene.Schema(query=Query))

@app.get('/')
async def graphiql(request: Request):
    request._url = URL('/gql')
    return await graphql_app.handle_graphiql(request=request)

@app.post('/gql')
async def graphql(request: Request, db: Session = Depends(deps.get_db)):
    request.state.db = db
    return await graphql_app.handle_graphql(request=request)