🍓

【Python】StrawberryとDjangoの組み合わせでContextの設定と取得

2024/04/19に公開

概要

PythonでGraphQLサーバーを実装する際にStrawberryというライブラリが候補に上がると思います。ライブラリの概要についてはGraphQLライブラリStrawberryのDjangoプロジェクトへの適用事例の資料をご参照ください。
StrawberryではGraphQLの各関数を呼び出す前に、Contextの領域に値の設定ができる処理が書けます。今回はStrawberryとDjangoを組み合わせた際の、Contextの実装をメモ書きします。

前提

  • 使用したライブラリstrawberry-graphql-djangoのバージョンは0.37.1です。

実装サンプル

リクエストのAuthorizationヘッダーからトークンを取得・複合化し、Contextに設定・取得する処理をサンプルとして実装します。

まずはContextの設定部分です。ここではリクエストのAuthorizationヘッダーのトークンを取得・複合化します。カスタムのGraphQLViewを別途設けて実装します。

class SampleGraphQLView(GraphQLView):
    # Contextに設定
    def get_context(self, request: HttpRequest, response: HttpResponse) -> Any:
        bearer_token: str = request.headers.get("Authorization", None)
        # 認証されてない場合はダミーのdictを返す
        if bearer_token == None or len(bearer_token.split(" ")) < 2:
            return {"dummy": "dummy"}

        # トークンを複合化してユーザIDを取得(処理の記載は割愛)
        decode_result = decode_jwt(bearer_token.split(" ")[1])
        if decode_result == None:
            return {"dummy": "dummy"}
        else:
            return {"user_account_id": decode_result}

カスタムのGraphQLViewをschemaに設定します。

urlpatterns = [
    path("admin/", admin.site.urls),
    path("graphql/", SampleGraphQLView.as_view(schema=schema)),
]

Contextに設定したユーザIDを、GraphQLの関数で取得します。

@strawberry.type
class SampleeQuery:
    @strawberry.field
    def get_sample_token(self, info: strawberry.Info) -> str:
        result_opt = info.context.get("user_account_id", None)
        if result_opt == None:
            raise GraphQLError(message="Failed authentication", extensions={"code": 401})

        return result_opt

その他参考

https://strawberry.rocks/docs/integrations/django

Discussion