Swagger 3.0のOAuth認証にCognito User PoolsのOAuth Clientを使う

Swaggerとは

Swaggerは、RESTful APIを構築するためのオープンソースのフレームワークのことを指します。APIをYAMLで定義でき、実際に呼び出すことができるようなインタラクティブドキュメントを生成できます。Amazon API Gatewayで使われていることでも有名です。

概要については下記のブログを参照してください。

(レポート) AWSモバイル/IoTサービス徹底攻略!! 「Swaggerで始めるモデルファーストなAPI開発」#cmdevio

Swagger 3.0とは

Swaggerのバージョンについては、現時点では2系がメジャーですが、3系も正式にリリースされたため、3系で書くケースも増えてきました。なお、API Gatewayは現時点では2系をサポートしています。

3系は、「2系でやりたかったけどできない!」という点が数多く改善され、非常に書きやすくなっています。仕様についてはOpen API Specificationにまとめられています。

OAuth認証の定義のしかた

Swagger 3.0では、定義しようとするAPIに認証が必要な場合、OAuthによる認証方法が定義できるようになりました。例えば次のような感じです。

components:
  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://example.com/oauth/authorize
          tokenUrl: https://example.com/oauth/token
          scopes:
            read: Grants read access
            write: Grants write access
            admin: Grants access to admin operations

これを見たときに お、Cognito User Poolsでもできそう… と思ったので、試してみました。

Swagger 3.0のOAuth認証にCognito User PoolsのOAuth Clientを使う

今回試したソースコードはGitHubで公開していますので、試してみたい方はぜひcloneしてみてください。

以下ではその手順をご紹介します。

Cognito User PoolsのOAuth Clientを作る

まず、Cognito User Poolsの設定です。

Cognito User Poolsの作成

作成手順は以下の記事と同じになりますので、参照しながら作成してください。

Angular+Cognitoで作るログインページ– ClassmethodサーバーレスAdvent Calendar 2017 #serverless #adventcalendar

OAuth Clientの作成

作成済みのCognito User Poolsに、OAuth Clientを作成します。

左メニューの「General settings」より「App clients」を選び、「Add an app client」をクリックします。以下のように設定します。

  • 「App client name」を任意の名前にする
  • 「Generate client secret」にチェックを入れる ※ デフォルトでチェックが入っています

作成後「App client id」と「App client secret」をメモしておきます(「App client secret」は「Show details」をクリックすると表示されます)。

次にApp clientを設定します。左メニューの「App integration」の「App client」を選択します。

先ほど作成したClientが表示されるので、以下のように設定します。

  • 「Enabled Identity Providers」で「Select all」にチェックを入れる
  • 「Callback URL(s)」に http://localhost:3200/oauth2-redirect.html を入力する
  • 「Sign out URL(s)」に http://localhost:3200/oauth2-redirect.html を入力する
  • 「Allowed OAuth Flows」の「Authorization code grant」にチェックを入れる
  • 「Allowed OAuth Scopes」の「openid」にチェックを入れる

特に「Callback URL(s)」の設定は、今回の構成では この値を必ず入れないと動かない 点に注意してください。

最後にドメインを振ります。左メニューの「App integration」の「Domain name」を選択し、有効なドメイン名を適当に付けます。あとで使うので覚えておいてください。

ここまでで、Cognito User Poolsの設定は終わりです。あとで使うので、ユーザーは1人作成しておくと良いでしょう。

Swaggerを書く

次にいよいよSwaggerを書いてみます。

まず適当な作業ディレクトリを用意し、その配下に swagger.yaml を書きます。以下の <your domain> の箇所は、先ほど設定したドメイン名に変更してください。

openapi: "3.0.0"
info:
  title: Simple API overview
  version: 1.0.0
components:
  securitySchemes:
    OAuth2:
      type: oauth2
      description: For more information, see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-userpools-server-contract-reference.html
      flows:
        authorizationCode:
          authorizationUrl: https://<your domain>.auth.ap-northeast-1.amazoncognito.com/oauth2/authorize
          tokenUrl: https://<your domain>.auth.ap-northeast-1.amazoncognito.com/oauth2/token
          scopes:
            openid: openid token
paths:
  /:
    get:
      operationId: listGet
      summary: List API versions
      security:
        - OAuth2: [openid]
      responses:
        200:
          description: 200 response
          content:
            application/json:

今回はSwaggerドキュメントを動かす環境としてSwagger-UIを使用します。Swagger-UIは、WebブラウザでAPIを試すことができるツールです。

Swagger-UIはDocker Imageが公開されているので、これを使うと簡単に構築できます。もしDockerをインストールしていない場合は、以下の記事を参考にインストールをしておいてください。

Public BetaになったDocker for Macを使ってみる

先ほど swagger.yaml を作成したディレクトリと同じ階層に docker-compose.yml を用意します。

version: '2'

services:
  swagger:
    image: swaggerapi/swagger-ui
    environment:
      API_URL: /swagger.yaml
      BASE_URL: /
    volumes:
      - ./swagger.yaml:/usr/share/nginx/html/swagger.yaml
    restart: always
    ports:
      - 3200:8080

以上で準備は終わりです。

試してみる

先ほど docker-compose.yml を用意したディレクトリで、以下のコマンドを実行します。

$ docker-compose up -d

起動に成功すると http://localhost:3200 にアクセスするとSwaggerのドキュメントを表示することができます。

「Authorize」というボタンがあるので、クリックします。

「client id」と「client secret」を入力するところがあるので、Cognito User Poolsの「App client id」と「App client secret」を入力し、「openid」にチェックを入れ、「Authorize」をクリックします。

Cognito User Poolsの認証画面が表示されるので、作成済みのユーザーの認証情報でログインします。

Swaggerにリダイレクトし、認証が通っている状態になります。

APIを呼び出してみると、Authorizationヘッダーにトークンが付与されていることがわかります。

Cognito User Poolsを使って認証するサービスを使う場合に最適!

Cognito User Poolsを使って認証・認可を行なっているサービスを作っている際、今回の構成でAPIドキュメントを作ると、Web上から簡単に試すことができるのでとても便利になります。ぜひお試しください!