Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
7
Help us understand the problem. What is going on with this article?

More than 3 years have passed since last update.

@bvlion

SwaggerのURLをlocalhostから特定のドメインに変更する

Swaggerは本当に便利ですね!
WEBを作る時には、常に入れたいと感じるありがたいFWです。
そのため基本的にはほぼデフォルトのままで十分使えるのですが、「Try it Out!」での接続先「localhost」を変え、検証環境や本番環境のURLを叩きたくなることもあろうかと思います。(あんまないかな?…)
ちょっとハマったので、今回はその際に設定したことを備忘録として残そうと思います。

今回やりたいこと

  • 「Try it Out!」のボタンで検証環境や本番環境のURLを叩きたい
    Try it Out!.png
  • ちゃんと閲覧制限も設けたい

環境

  • SpringBoot 1.5.4.RELEASE
  • Java 8
  • Gradle 2.13
  • Swagger(springfox) 2.7.0
  • Nginx 1.6.2

SpringBootにSwaggerを導入

詳しい導入方法に関しては多数の記事がございますので、そちらをご参照いただければと思います。
ここでは、最低限の内容に留めさせていただきます。

build.gradle

build.gradle
.....

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')

    compile('io.springfox:springfox-swagger2:2.7.0')
    compile('io.springfox:springfox-swagger-ui:2.7.0')
}

.....

SwaggerConfig.java

SwaggerConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.Collections;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket swaggerSpringMvcPlugin() {
        return new Docket(DocumentationType.SWAGGER_2)
                .protocols(Collections.singleton("https")) // <- ポイント 1
                .host("example.com") // <- ポイント 2
                .select()
                .apis(RequestHandlerSelectors.basePackage("対象パッケージ"))
                .build()
                .apiInfo(apiInfo());
    }

    private ApiInfo apiInfo() {
        return new ApiInfo(
                "APIのタイトル",
                "APIの詳細",
                "バージョン",
                "利用規約のURL",
                new Contact(
                        "名前(会社名とか?)",
                        "会社等のWebサイトURL",
                        "メールアドレス"
                ),
                "ライセンス",
                "ライセンスのURL",
                Collections.emptyList() /* ベンダー拡張( ?(^^; ) */
        );
    }
}

ポイントはDocketに定義されている「protocols」と「host」を使うところです。
もしポートを指定したい場合は「.host("example.com:8080")」と書けばいいようです。
試してはいませんが、protocolsがSetなので、「http」と「https」や、他のURLスキームも可能なのかもしれません。
調べ方が悪かったのか、あまりこの情報が出てこず、ソースを追ったら見つけました♪

閲覧制限設定

ここまで設定して実行(本番にデプロイ)すれば、「Try it Out!」での接続先URLが変わった状態で見れるようになるかと思います。
ただ、それではセキュリティ的に問題が出そうなので、私は以下のような設定を行いました。

default.conf
# 大元設定 {{{
server {
      listen 443 default ssl;
      server_name example.com;
      # 基本設定 {{{
      server_tokens off;

      ssl on;
      ssl_certificate /etc/nginx/conf.d/ssl/example.pem;
      ssl_certificate_key /etc/nginx/conf.d/ssl/example.key;

      # }}}

      # SpringBoot設定 {{{
      location / {
          set $test 1;
          if ($http_user_agent = "ユーザーエージェントで分岐") {
            set $test 0;
          }
          if ($remote_addr = "IPで分岐") {
            set $test 0;
          }
          if ($test = 1) {
              return 404;
          }
          proxy_pass  http://localhost:ポート番号;
      } # }}}
} # }}}

私の場合はちょっと特殊なAPIであるため、全てでUAまたはIPの制限を入れる必要があるので上記のようにしていますが、もちろんSpringBoot側(WebSecurityConfigurerAdapterを継承して作るとか)でもOKですし、Swaggerで使用されるURLのみを制限するという方法でもOKだと思います!

注意点 1

Swaggerで使用されるURLのみを制限する場合、以下を対象にする必要があります。

  • /v2/api-docs
  • /swagger-resources*
  • /swagger-ui.html
  • /webjars/**

「/v2/api-docs」に気づかず苦戦しました。。。
表示後、/v2/api-docsのデータを展開して表示するんですね(>_<)

注意点 2

さすがにセッションまではいい具合にやってもらえません。。。
ここも工夫の余地がありそうです。
例えば特定のURLを叩くとUsernamePasswordAuthenticationTokenをnewしてAuthenticationManager.authenticateでセットしてくれる機能を作るとかですかね?
難しい…(´・ω・`)

まとめ

  • Docketを生成するときに「protocols」と「host」を設定すれば「Try it Out!」のURLを変えられる
  • ポートはhostの引数に直接書く
  • 「/v2/api-docs」から表示データは取得されるため閲覧制限時は注意する
  • セッションまでは上手く操作できないので別途構築を検討する

Swaggerは他にも色々と設定できる項目があるようです。
個人勉強であれば、色々試してみたいですね!

7
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
7
Help us understand the problem. What is going on with this article?