I am having trouble implementing authentication verification in an GraphQL Server built with FastAPI. Before, we were using REST but now we are switching to GraphQL and I am wondering how I can implement this. Before, we had different routers and with FastAPI it is easy to check authentication based on routes using dependencies as in here. We are sending a Token in the Authorization Header which we are decoding in the backend and getting back the user_id which we can then use in our different endpoints.
I am wondering how this might work using GraphQL here. We use the Graphene and I had a look at Starlettes Authentication Examples as well as there intro into setting up GraphQl
import binascii
from fastapi import FastAPI
from starlette.authentication import (
AuthenticationBackend, AuthenticationError, SimpleUser, AuthCredentials
)
from starlette.graphql import GraphQLApp
from starlette.middleware import Middleware
from starlette.middleware.authentication import AuthenticationMiddleware
from schemas.root import my_schema
class BasicAuthBackend(AuthenticationBackend):
async def authenticate(self, request):
if "Authorization" not in request.headers:
raise AuthenticationError('No auth credentials')
auth = request.headers["Authorization"]
try:
id_token = auth.split('Bearer ')[1]
decoded_token = auth.verify_id_token(id_token)
except (ValueError, UnicodeDecodeError, binascii.Error) as exc:
raise AuthenticationError('Invalid basic auth credentials')
user_id = decoded_token['uid']
return AuthCredentials(["authenticated"]), user_id
middleware = [
Middleware(AuthenticationMiddleware, backend=BasicAuthBackend())
]
my_schema = Schema(
query=RootQuery,
mutation=RootMutation,
)
api = FastAPI(title=f"MyGraphQLServer", middleware=middleware)
api.add_route("/graphql", GraphQLApp(schema=my_schema))
For example, imagine that I now would only like to authenticate mutation Requests but not query requests. Furthermore I want to access the user_id in each of my resolvers. What would be the best way to do this?