techium

このブログは何かに追われないと頑張れない人たちが週一更新をノルマに技術情報を発信するブログです。もし何か調査して欲しい内容がありましたら、@kobashinG or @muchiki0226 までいただけますと気が向いたら調査するかもしれません。

既存 Rails アプリに追加した REST API ドキュメンテーションにOAuth2 認可情報を反映する

既存 Rails アプリに追加した REST API ドキュメンテーションにOAuth2 認可情報を反映する

回を追うごとにタイトルが長くなっていくのはご愛嬌。

Rails チュートリアルで作成したアプリに
- REST API を追加 - OAuth2 で保護 - Swagger でドキュメンテーション

と進めてきた。

前回の Swagger ドキュメンテーションではセキュリティの定義をしていないので追加していく。

Swagger の SecurityDefinition

OAuth 2

This page is in progress. Please check back later.

まぁオープンソースだしね、文句があるなら自分でパッチ送れや的な?

GrapeSwaggerRails の doorkeeper 連携

そもそも GrapeSwaggerRails が doorkeeper と連携できるんでは?と思って見てみたらやはり。

Integration with DoorKeeper

user.rb は上記例の通り。

has_one :token, -> { order 'created_at DESC' }, class_name: Doorkeeper::AccessToken, foreign_key: :resource_owner_id

swagger.rb は、以下のようにある。

GrapeSwaggerRails.options.before_action do |request|
  GrapeSwaggerRails.options.api_key_default_value = current_user.token.token
end

最終的な GrapeSwaggerRails.options.before_action は以下のようになった。

GrapeSwaggerRails.options.before_action do |request|
  GrapeSwaggerRails.options.app_url = request.protocol + request.host_with_port

  if (user_id = session[:user_id])
    current_user ||= User.find_by(id: user_id)
    if (current_user_token = current_user.token)
      GrapeSwaggerRails.options.api_key_default_value = current_user_token.token
    end
  else
    session[:forwarding_url] = request.fullpath
    redirect_to(GrapeSwaggerRails.options.app_url + '/login')
  end
end

さらに こちら を参考に、api_key の値をクエリパラメータでは無くヘッダーで渡すよう設定する。

GrapeSwaggerRails.options.api_auth     = 'bearer'
GrapeSwaggerRails.options.api_key_name = 'Authorization'
GrapeSwaggerRails.options.api_key_type = 'header'

これで、irb から AccessToken 取得まで進めておけば、そのユーザーでログインした(セッションが有効な)状態で https://host:port/swagger にアクセスすればアクセストークンを api_key として持った状態で Swagger UI が表示できる。
各 API の Try it out! ボタンも正常に動作する。

その他

irb 使わなくても、Swagger UI から認可のフローが実行できないものか。。?
ちょっと だいぶ調べて、できそうなんだけどうまくいかないので断念。

api/v1/root.rb に以下を追加したところ、Swagger の json には SecurityDefinition の定義もできているが、Authorize 用の UI が表示されない。

    add_swagger_documentation \
    info: {
      title: "SAMPLE APP",
      description: "This is the sample application for the tutorial.",
      contact_name: "kfurue",
      contact_email: "contact@example.com",
      contact_url: "http://example.com/contact",
      license: "the MIT License",
      license_url: "http://example.com/license"
    },
    security_definitions: {
      oauthAccessCode: {
        type: "oauth2",
        authorizationUrl: "https://host:port/oauth/authorize",
        tokenUrl: 'https://host:port/oauth/token',
        flow: "accessCode",
        scopes: {
          user: "User scope"
        }
      },
      oauthImplicit: {
        type: "oauth2",
        authorizationUrl: "https://host:port/oauth/authorize",
        flow: "implicit",
        scopes: {
          user: "User scope"
        }
      }
    }

GrapeSwaggerRails のせいか?と思い、grape-swagger で生成した JSON を元に、ローカルで Swagger UI を立ち上げてみるとなるほど、Authorization 用の UI は出てくる。 が、今度は

Validation Erroroauth2RedirectUri configuration is not passed. Oauth2 authorization cannot be performed.

などと表示されて認可フローは通せず。

まだまだ壁は多そうなのでここらで諦めよう。
やりたいことはできてるっぽいし?