ตัวอย่างการเขียน Spring-boot Reactive Cors (Cross-origin resource sharing)
- ทำความเข้าใจเรื่อง Cors ได้จาก https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
pom.xml
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>build-info</goal>
</goals>
<configuration>
<additionalProperties>
<java.version>${java.version}</java.version>
</additionalProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
หมายเหตุ lombox เป็น annotation code generator ตัวนึง
@SpringBootApplication
@ComponentScan(basePackages = {"me.jittagornp"})
public class AppStarter {
public static void main(String[] args) {
SpringApplication.run(AppStarter.class, args);
}
}
@Slf4j
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping
public Flux<User> findAll() {
...
}
@GetMapping("/{id}")
public Mono<User> findById(@PathVariable("id") final String id) {
...
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Mono<User> create(@RequestBody final User user){
...
}
@PutMapping("/{id}")
public Mono<User> update(@PathVariable("id") final String id, @RequestBody final User user){
...
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public Mono<Void> deleteById(@PathVariable("id") final String id) {
...
}
@GetMapping("/me")
public Mono<User> getUser() {
...
}
}
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsWebFilter() {
final CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList("*"));
config.setMaxAge(Duration.ofMinutes(1));
config.setAllowedMethods(Arrays.asList(
HttpMethod.GET.name(),
HttpMethod.POST.name(),
HttpMethod.PUT.name(),
HttpMethod.PATCH.name(),
HttpMethod.DELETE.name(),
HttpMethod.OPTIONS.name(),
HttpMethod.HEAD.name()
));
config.setAllowedHeaders(Arrays.asList(
HttpHeaders.CONTENT_TYPE,
HttpHeaders.AUTHORIZATION,
HttpHeaders.IF_MATCH,
HttpHeaders.IF_MODIFIED_SINCE,
HttpHeaders.IF_NONE_MATCH,
HttpHeaders.IF_UNMODIFIED_SINCE,
"X-Requested-With"
));
config.setExposedHeaders(Arrays.asList(
HttpHeaders.ETAG,
HttpHeaders.LINK,
"X-RateLimit-Limit",
"X-RateLimit-Remaining",
"X-RateLimit-Reset"
));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}
config.setAllowedOrigins(Arrays.asList("*"))
คือ Allow ทุก Origin (ทุก Domain Name) ให้สามารถ call Ajax จากที่ไหนก็ได้config.setMaxAge(Duration.ofHours(1));
ทำการ Cached Preflight Request (OPTIONS
) ไว้ 1 ชั่วโมงconfig.setAllowedMethods(...)
อนุญาตให้ call Ajax ด้วย Http Method ดังต่อไปนี้ได้config.setAllowedHeaders(...)
อนุญาตให้ส่ง Headers ดังต่อไปนี้มาได้config.setExposedHeaders(...)
อนุญาตให้ Client อ่าน Response Headers ดังต่อไปนี้ได้source.registerCorsConfiguration("/**", config);
ใช้ Cors กับทุก ๆ Path
cd ไปที่ root ของ project จากนั้น
$ mvn clean package
$ mvn spring-boot:run