認証済みのユーザーにのみリクエストを許可したい特定のフィールとは権限のあるユーザーのみに公開したいといったアクセス制御を行いたい場面は存在するかと思います。今回は、そのような認証機構をサーバーに追加する様子を紹介します。Authorizationヘッダーによる認証機構の追加まずは「Authorizationヘッダーにトークンが入っているかどうか判定する」機構を組み込みたいと思います。HTTPリクエストの中身を見る機構はGraphQL層の前にGraphQLサーバーがレスポンスに必要なデータを集めてくる処理は全てリゾルバの中で行っていましたが、リゾルバ関数の中には「HTTP通信」の要素を感じられるような引数は存在しません。nodeクエリに対応するリゾルバを以下に示します。引数に入っているのは、ユーザーがリクエスト時に渡したidパラメータとcontextのみであり、http.Request型のようなnet/httpパッケージにあるような素のHTTP通信を彷彿とさせる要素は存在しません。error)これは、GraphQLのリゾルバが「レスポンスに必要なデータを集めて、それを構造体型といったある種の決まった値にまとめる」というところに集中できるよう、「データをjsonエンコードしてhttp.ResponseWriterに書き込む」などのHTTP通信に関わる部分を隠蔽された状態のものだからです。そのため、リクエストヘッダーのようなHTTPリクエストに関わる生データが見たいというのであれば、そのような処理はリゾルバの前段に入れる必要があるのです。認証ミドルウェアの作成ディレクトリ・ファイルの作成HTTPリクエストの中身を見るような前後処理を挟むためには、通常のHTTPサーバーを作るときと同様の手段でミドルウェアを実装すれば良いのです。そのためのパッケージとファイルを作りましょう。Unauthorizedを返却するという処理を行うミドルウェアを実装します。作成したミドルウェアをGraphQLサーバーに導入するには、サーバー起動時にミドルウェアを使用するようにラップすればOKです。nil))}動作確認この状態でサーバーを稼働させ、本当にトークンを利用した認証の仕組みが動いているのか確認してみましょう。トークンなしの状態まずは普通にリクエストを送ってみます。}}すると、以下のような正常応答が返ってくることがわかります。以下のように、UT_xxxという形のトークンをヘッダにつけてリクエストを送ってみます。"UT_hsaki"}すると、以下のような正常応答が返ってくることがわかります。}}無効なトークンを使った場合UT_xxxという形になっていないめちゃくちゃなトークンも送ってみます。token"というエラーを得られて、GraphQLによるデータ取得処理にたどり着いていないことが確認できました。token"}ディレクティブを利用したGraphQL層での認証機構の追加GraphQL層には認証認可の機構を組み込めないのか、というとそうではありません。ここからは「Authorizationヘッダーの中からユーザー情報をとってこれた場合のみ、userクエリを実行できるようにする」というアクセス制御を追加してみたいと思います。ディレクティブとはGraphQLのスキーマには、ディレクティブというカスタムデコレータを追加することができます。今回の場合、userクエリを定義するところに@isAuthenticatedというディレクティブをつけていました。@isAuthenticated}しかし、ただディレクティブをつけただけでは「〇〇の条件のときには~する」といったフック処理を実現させることはできません。そのように実装を追加する必要があるので、これからその作業をしていきましょう。ディレクティブごとの処理をサーバーConfigで指定するサーバーで利用するディレクティブごとのフック処理は、サーバーエンドリポイントにて記述するConfigの内容で決定されます。nil))}internal.Config構造体の内容と、そのConmplexityフィールドの内容に何を指定すればいいのかは、gqlgenコマンドによって自動生成されたコード内にて定義が記述されています。error)の関数シグネチャにあう形で、フック処理を実装する1で作成した関数をIsAuthenticatedフィールドに詰めたDirectiveRoot構造体を作る2で作成したDirectiveRoot構造体をDirectivesフィールドに詰めたサーバーConfigを作成して使用するという流れを踏むことになります。ディレクティブのフック処理実装それではここからは実際にその実装をしていきましょう。ファイルの作成ディレクティブによる処理を記述するためのファイルをまずは作成します。error)の関数シグネチャにあう形で、フック処理を実装し、それをIsAuthenticatedフィールドに詰めたDirectiveRoot構造体を作る」という部分をやっていきます。false}}今回は「Authorizationヘッダーに格納されていたトークンから取得したユーザー情報がcontextに格納されていた場合には処理を実行する」というロジックにしてみました。Configをサーバーに反映@isAuthenticatedディレクティブが指定されたときの処理をConfigに実装できたため、それをサーバーの中で使用できるようにします。nil))}動作確認この状態でサーバーを稼働させ、本当に「トークン認証できているときのみuserクエリが実行可能」になっているかどうか確認してみましょう。先ほどと同様に、以下のようなuserクエリを送信します。}}すると、以下のようなエラーが返ってきて、クエリが実行できていないことがわかります。}}有効なトークンをつけてリクエスト今度は以下のように、UT_xxxから始まる有効なトークンを付与してuserクエリを実行します。"UT_hsaki"}すると、無事にレスポンスデータを得ることができました。