Swaggerは本当に便利ですね!
WEBを作る時には、常に入れたいと感じるありがたいFWです。
そのため基本的にはほぼデフォルトのままで十分使えるのですが、「Try it Out!」での接続先「localhost」を変え、検証環境や本番環境のURLを叩きたくなることもあろうかと思います。(あんまないかな?…)
ちょっとハマったので、今回はその際に設定したことを備忘録として残そうと思います。
今回やりたいこと
環境
- SpringBoot 1.5.4.RELEASE
- Java 8
- Gradle 2.13
- Swagger(springfox) 2.7.0
- Nginx 1.6.2
SpringBootにSwaggerを導入
詳しい導入方法に関しては多数の記事がございますので、そちらをご参照いただければと思います。
ここでは、最低限の内容に留めさせていただきます。
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
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が変わった状態で見れるようになるかと思います。
ただ、それではセキュリティ的に問題が出そうなので、私は以下のような設定を行いました。
# 大元設定 {{{
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は他にも色々と設定できる項目があるようです。
個人勉強であれば、色々試してみたいですね!