echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

【AppSync】Auth0 + OpenID Connect認証でGraphQLクエリを実行する(内容修正版)

はじめに

先日、初めて業務でAWS AppSync(以下AppSync)とGraphQLを使いました。
サブスクリプションが使えたり、クライアント側からフィールド指定出来たりできるのが良い感じです。
あと、エンドポイントの管理がAPI Gatewayより楽ですね。(無論、デメリットもありますが)

ただAPI Gatewayもそうですが、アプリとして使う以上避けては通れないのが「認証」です。

今回は、そんなAppSyncの認証の中から「OIDC(OpenID Connect)認証」のやり方を説明したいと思います。

またOIDC認可サーバーには、Auth0を使いたいと思います。

TL;DR

  • AppSyncでOpenID Connect(以下OIDC)認証を使う方法
  • OIDC認証にはAuth0を使用
  • AppSyncコンソール&クライアント(今回はRest Client)からクエリを実行する方法

注意

(2021/8/27記載) とりあえず自分の備忘録的にまとめたので、本当にメモ書き程度になってます。
時間があれば、もう少し丁寧な文章に直します。

※2021/9/11追記:直しました

参考blog

AWS AppSyncでAuth0を認証プロバイダーとしたOIDCを設定する | DevelopersIO

やること

  • Auth0の設定
  • AppSyncの設定
  • クエリ実行

Auth0の設定

※Auth0のアカウントは持ってる前提で進めます。
※持っていない場合はあらかじめ取得しておいてください。

APIの新規作成

左ツリーから[Applications] - [APIs]を選択し、右に表示される[Create API]ボタンをクリックしてください。

すると「New API」画面が表示されるので、下記項目を入力して「Create」ボタンをクリックしてAPIを新規作成してください。(すべて必須項目)

項目 説明
Name APIの名前
Identifier APIの一意の識別子。APIエンドポイントURLが推奨。(違っててもいい)
Signing Algorithm 署名アルゴリズム必ず「RS256」を選択すること!(「HS256」はダメ)

プロバイダードメインの確認(「AppSyncの設定」で必要)

左ツリーの[Applications] - [Application]を選択し、「APIの新規作成」の「Name」と同名のApplicationをクリックします。

するとアプリの情報が表示されますが、その「Settings」タブ内の「Domain」に記載のURLがプロバイダードメインになります。
f:id:Makky12:20210911190818p:plain

アクセストークンの確認(「クエリ実行」で必要)
再度左ツリーから[Applications] - [APIs]を選択し、「APIの新規作成」で作成したAPIをクリックします。
APIの情報が表示されるので、「Test」タブをクリックし、その中の「response」項目に移動します。(プログラム言語のタブは何でもいい)

その中の「access_token」キーの値が、そのままアクセストークンの値になります。
f:id:Makky12:20210911191800p:plain

てか、認証処理を実施せずともアクセストークンが確認できるのは、すごい便利だなと感じました。

AppSyncの設定

※AppSync APIは作成済の前提で進めます。
※作成していない場合はあらかじめ作成しておいてください。

作成したAppSync APIをクリックし、左ツリーの「設定」をクリックします。 すると設定画面が開くので、「デフォルトの認証モード」項目で、下記項目に下記の値を入力して「保存」をクリックします。

  • APIレベル」:「OpenID Connect」
  • OpenID Connect プロバイダードメイン (発行者 URL)」:「Auth0の設定」の「プロバイダードメインの確認」で確認したプロバイダードメイン
    • https://」始まりであることに注意してください。

f:id:Makky12:20210911194540p:plain

クエリ実行

では、準備はできたので、実際にクエリを実行しましょう。
今回はAppSyncコンソール、およびクライアントPCから実行ます。

AppSyncコンソールから実行

  • 作成したAppSync APIをクリックし、左ツリーの「クエリ」をクリックします。
  • その後、「使用する認証モード」が「AppSyncのOIDC認証設定」の「プロバイダードメイン名」が選択されていることを確認します。
    • これはデフォルトでなっているはずです。
  • 何かしらクエリを記載し、右上の「Authorization Token」に「Auth0の設定」の「アクセストークンの確認」で確認したアクセストークンをコピペします。
  • 「クエリ実行」ボタンをクリックし、クエリを実行します。

これでクエリが実行され、正しく実行結果が表示できるはずです。
f:id:Makky12:20210911194914p:plain

また、アクセストークンが未設定or間違っているなら、結果が「Request failed with status code 401」となります。
f:id:Makky12:20210911194945p:plain

クライアントから実行(今回はRest Client)
※今回はリクエストにVS Codeの定番拡張機能である「Rest Client」を使っていますが、リクエスト方法は何でもいいです。

下図のように、以下ヘッダを設定して、クエリをPOSTリクエストして実行します。

  • Method:POST(GETではない)
  • 「X-REQUEST-TYPE」:「GraphQL」固定
  • 「Authorization」:「アクセストークン確認方法」に記載のaccess_token
  • Bodyに実行するクエリ、および変数の値を設定する。
  • URLは- AppSyncコンソールの「設定」内の「API Details」-「API URL」に記載されているURL

これもアクセストークンが正しいなら、正しくクエリ実行結果がレスポンスで返ってくるはずです。
またアクセストークンが未設定or間違っているなら、「UnauthorizedException」が返ってくるはずです。      f:id:Makky12:20210911195851p:plain
f:id:Makky12:20210911195904p:plain

まとめ

以上がAuth0 + OpenID Connect認証でGraphQLクエリを実行する方法でした。

OIDC認証と聞くと難しそうですが、Auth0を使うと驚くほど簡単に設定できてしまうので、自分でもびっくりしました。
てかAuth0、めちゃくちゃ便利ですね。マジで衝撃でした。

さて今後ですが、AppSync認証にはOIDC以外にも方法があるので、その中からLambda認証あたりをブログにしようかな?なんて考えてます。

それでは、今回はこの辺で。

参考:RestAPI(API Gateway)と比べたGraphQL API(AppSync)のメリット・デメリット

メリット

  • Web API実行URLの管理が容易
    • API Gatewayと違い、AppSyncはクエリ/ミューテーションがどれだけ増えようと、Web API実行URLが1つなので、URLの管理が容易です。
      • API GatewayはWeb APIが増えれば増えるほど、Web API実行URLが増えます。
    • ただしAppSyncは「スキーマの管理が厄介」の問題があるので、結果イーブンかも
  • サブスクリプション機能で、変更を即座にクライアントに通知できる
    • GraphQLには「サブスクリプション」の機能があり、これを使用することで、データに変更があった場合、即座にクライアントにそれを通知できます。
    • ただしサブスクリプションの使用には、WebSocketが必要になります。
  • 必要なフィールドをクエリ発行側(≒クライアント)が指定できる
    • 必要なフィールドをクエリ発行側が指定することができ、以下のメリットがあります。
      • 必要最小限なフィールドを指定する事で、データ通信量の削減が可能
      • (少ない通信量で)同一クエリの使いまわしが可能

デメリット

  • スキーマの管理が厄介
    • GraphQLでは、「スキーマ」と呼ばれる定義ファイルにクエリ/ミューテーション/サブスクリプションなどを定義し、管理することになります。
    • Web API実行URLは1つですが、その分スキーマの管理の手間が増えます。(さっき「結果イーブンかも」と書いたのはそのため)
  • マッピングテンプレートが面倒
    • リソルバには「マッピングテンプレート」があり、リクエスト/レスポンスそれぞれでこのマッピングテンプレートを記載する必要があります。
    • これは「Apache Velocity テンプレート言語 (VTL)」で書くのですが、これがなかなか面倒だったりします。
    • ただし、リソルバに「ダイレクトLambdaリソルバ」を使用する場合に限り、マッピングテンプレートを記載せずともOKです。
  • クエリ/ミューテーション個別の設定がやりにくい
    • Web API実行URLは1つである分、クエリ/ミューテーション個別の設定はやりにくいです。
    • 例えば「クエリAは未ログインでも実行可能/クエリBはログイン者のみ実行可能」という場合でも、クエリA/Bそれぞれに個別にオーソライザを設定できないため、不便になります。