diff --git a/backend/open-isle.env.example b/backend/open-isle.env.example
index 8e2d0b4b4..ab3549c04 100644
--- a/backend/open-isle.env.example
+++ b/backend/open-isle.env.example
@@ -1,3 +1,6 @@
+# === Spring Boot ===
+SERVER_PORT=8080
+
# === Database ===
MYSQL_URL=jdbc:mysql://<数据库地址>:<端口>/<数据库名>?useUnicode=yes&characterEncoding=UTF-8&useInformationSchema=true&useSSL=false&serverTimezone=UTC
MYSQL_USER=<数据库用户名>
diff --git a/backend/pom.xml b/backend/pom.xml
index 4193590b6..dd3bcf62c 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -114,6 +114,11 @@
bcprov-jdk15on
1.70
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-api
+ 2.2.0
+
@@ -141,6 +146,26 @@
+
+
+
+ org.springdoc
+ springdoc-openapi-maven-plugin
+ 1.4
+
+
+
+ generate
+
+
+
+
+
+ http://localhost:8080/v3/api-docs
+ openapi.json
+ ${project.build.directory}
+
+
diff --git a/backend/src/main/java/com/openisle/config/OpenApiConfig.java b/backend/src/main/java/com/openisle/config/OpenApiConfig.java
new file mode 100644
index 000000000..5af5cf000
--- /dev/null
+++ b/backend/src/main/java/com/openisle/config/OpenApiConfig.java
@@ -0,0 +1,48 @@
+package com.openisle.config;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.security.SecurityRequirement;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class OpenApiConfig {
+
+ @Value("${springdoc.info.title}")
+ private String title;
+
+ @Value("${springdoc.info.description}")
+ private String description;
+
+ @Value("${springdoc.info.version}")
+ private String version;
+
+ @Value("${springdoc.info.scheme}")
+ private String scheme;
+
+ @Value("${springdoc.info.header}")
+ private String header;
+
+ @Bean
+ public OpenAPI openAPI() {
+ SecurityScheme securityScheme = new SecurityScheme()
+ .type(SecurityScheme.Type.HTTP)
+ .scheme(scheme.toLowerCase())
+ .bearerFormat("JWT")
+ .in(SecurityScheme.In.HEADER)
+ .name(header);
+
+ return new OpenAPI()
+ .info(new Info()
+ .title(title)
+ .description(description)
+ .version(version))
+ .components(new Components()
+ .addSecuritySchemes("JWT", securityScheme))
+ .addSecurityItem(new SecurityRequirement().addList("JWT"));
+ }
+}
diff --git a/backend/src/main/java/com/openisle/config/SecurityConfig.java b/backend/src/main/java/com/openisle/config/SecurityConfig.java
index bb6081aac..a3381d934 100644
--- a/backend/src/main/java/com/openisle/config/SecurityConfig.java
+++ b/backend/src/main/java/com/openisle/config/SecurityConfig.java
@@ -106,6 +106,7 @@ public class SecurityConfig {
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.requestMatchers("/api/ws/**", "/api/sockjs/**").permitAll()
+ .requestMatchers("/v3/api-docs/**").permitAll()
.requestMatchers(HttpMethod.POST, "/api/auth/**").permitAll()
.requestMatchers(HttpMethod.GET, "/api/posts/**").permitAll()
.requestMatchers(HttpMethod.GET, "/api/comments/**").permitAll()
@@ -176,7 +177,8 @@ public class SecurityConfig {
return;
}
} else if (!uri.startsWith("/api/auth") && !publicGet
- && !uri.startsWith("/api/ws") && !uri.startsWith("/api/sockjs")) {
+ && !uri.startsWith("/api/ws") && !uri.startsWith("/api/sockjs")
+ && !uri.startsWith("/v3/api-docs")) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.getWriter().write("{\"error\": \"Missing token\"}");
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index 9e81189ed..60ed00d19 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -1,3 +1,6 @@
+# for spring boot
+server.port=${SERVER_PORT:8080}
+
# for mysql
logging.level.root=${LOG_LEVEL:INFO}
logging.level.com.openisle.service.CosImageUploader=DEBUG
@@ -83,3 +86,13 @@ app.website-url=${WEBSITE_URL:https://www.open-isle.com}
# Web push configuration
app.webpush.public-key=${WEBPUSH_PUBLIC_KEY:}
app.webpush.private-key=${WEBPUSH_PRIVATE_KEY:}
+
+# springdoc-openapi-starter-webmvc-api
+# see https://springdoc.org/#springdoc-openapi-core-properties
+springdoc.api-docs.path=/v3/api-docs
+springdoc.api-docs.enabled=true
+springdoc.info.title="OpenIsle"
+springdoc.info.description="OpenIsle Open API Documentation"
+springdoc.info.version=0.0.1
+springdoc.info.scheme=Bearer
+springdoc.info.header=Authorization