既存 Rails アプリに追加した REST API ドキュメンテーションにOAuth2 認可情報を反映する
既存 Rails アプリに追加した REST API ドキュメンテーションにOAuth2 認可情報を反映する
回を追うごとにタイトルが長くなっていくのはご愛嬌。
Rails チュートリアルで作成したアプリに
- REST API を追加
- OAuth2 で保護
- Swagger でドキュメンテーション
と進めてきた。
前回の Swagger ドキュメンテーションではセキュリティの定義をしていないので追加していく。
Swagger の SecurityDefinition
This page is in progress. Please check back later.
まぁオープンソースだしね、文句があるなら自分でパッチ送れや的な?
GrapeSwaggerRails の doorkeeper 連携
そもそも GrapeSwaggerRails が 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.
などと表示されて認可フローは通せず。
まだまだ壁は多そうなのでここらで諦めよう。
やりたいことはできてるっぽいし?