Skip to main content

Command Palette

Search for a command to run...

CORS和在Spring Framework裡的應用

Updated
2 min readView as Markdown

Intro

Cross-Origin Resource Sharing (CORS) MDN Spec

為了防止XSS Attack,也就是惡意的JS讓使用者發請求到第三方網站,瀏覽器會限制XHR Request只能發到同一個origin。CORS Header讓伺服器端可以設定允許的origin。

Specifications

Simple Request & Preflight Request

Simple Request: GET, HEAD, POST with Origin Header Preflight: OPTIONS with specific headers request before real request.

Preflight Request Headers

  • Access-Control-Request-Method : Specify the coming request method
  • Access-Control-Request-Headers:

CORS respose headers

- Access-Control-Allow-Origin : **main header concerned**
  • Access-Control-Allow-Credentials: Is credentials allowed (cookies..etc)
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers: which HTTP headers can be used during the actual request.
  • Access-Control-Max-Age
  • Access-Control-Expose-Headers: response header allows a server to indicate which response headers should be made available to scripts running in the browser

Fetch Metadata Request Header

sec-fetch-mode will be cors .

https://developer.mozilla.org/en-US/docs/Glossary/Fetch_metadata_request_header

  • 瀏覽器在fetch時會提供metadata,讓Server知道是怎麼樣的請求,比如說是XHR還是直接的request

  • Sec-Fetch-Site

    • cross-site: different domain
    • same-origin: same origin
    • same-site: same subdomain (e.g. sub.example.com and example.com)
    • none: user triggered request (directly in URL bar, bookmark, other application ..etc)
  • Sec-Fetch-Mode
    • cors: [[CORS]] request
    • navigate: normal navigation between HTML documents
    • no-cors
    • same-origin
    • websocket
  • Sec-Fetch-User
    • Always ?1 if the request is initiated by user.
  • Sec-Fetch-Dest
    • In what element will be used e.g. audio, image, iframe, document ..etc

Use curl to send CORS requests

Normal request

$ curl -X GET -H "Origin: https://example.com" https://foo.com/aaabbcc

Preflight request

$ curl -X OPTIONS -H "Access-Control-Request-Method: GET" -H "Origin: https://example.com" https://foo.bar/api/

Send CORS in browser

Open console tab in development mode and use fetch(url)

Spring Boot / Spring Framework

Ref links:

  • https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-cors
  • https://spring.io/guides/gs/rest-service-cors/
  • https://blog.csdn.net/f641385712/article/details/101036506
  • https://www.cnblogs.com/leftthen/p/6378090.html

Implementation

https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/web/cors/DefaultCorsProcessor.java

Support Preflight Requests

OPTIONS request is by default supported https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-requestmapping-head-options

By default, HTTP OPTIONS is handled by setting the `Allow` response header to the list of HTTP methods listed in all `@RequestMapping` methods that have matching URL patterns.

### @CrossOrigin Annotation
https://docs.spring.io/spring-framework/docs/5.3.14/javadoc-api/org/springframework/web/bind/annotation/CrossOrigin.html

Applying to a controller method
Main options: origins, originPatterns(>= 5.3), methods

Java Configuration

Global config in [[Spring Framework]]

package ...;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfiguration {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**").allowedOrigins("https://example.com");
            }
        };
    }
}
  • https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/CorsRegistry.html#addMapping-java.lang.String-
  • https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/CorsRegistration.html#allowedOrigins-java.lang.String...-

note: can't use wildcard in allowedOrigins. Only allowedOriginPatterns.

-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/CorsRegistry.html

Detailed settings for CORS:

registry.addMapping("url") // -> returns  CorsRegistration
registry.addMapping("url").allowedOrigins(...).allowedHeaders(...).allowCredentials(...)

registry.addMapping("url").allowOriginPatterns() // Spring >= 5.3
  • https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/CorsRegistration.html

AWS Cloudfront

https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/

If CORS related headers are wrongly cached, the behavior would be strange.

Solutions:

  1. Add CORS related headers to cache key
  2. Use origin request policy
  3. Use managed origin request policy

More from this blog

探討系統時間與應用程式的影響:網路協定、誤差、以及正確使用方法

上一集我們討論了MySQL Timestamp 的精準度,提到了不同主機之間很有可能有時間差異,那這個時間差會有多大? 在電腦和許多微控器裡面都有一個 RTC 晶片,利用石英振盪器提供系統時間。這個RTC在一班桌上型電腦上就是裝在主機板上,和BIOS一起用水銀電池供電。所以如果那個電池如果沒電了,BIOS設定都會跑掉,時間也會被重設。 關於石英振盪器,這裡有一篇Analog Devices的文章解釋石英振盪器的原理以及誤差。 在 Linux 上,我們可以利用 hwclock獲取時間。但是這件事...

Mar 2, 20231 min read

MySQL的Timestamp準確度、快取應用的雷點

MySQL是常用的關聯式資料庫管理系統,其中Timestamp類型是一種用來儲存日期和時間的資料類型。在定義Timestamp欄位時,如果不定義準確小數點 的話,預設只到秒,且會四捨五入。 比如以下的資料表定義,就明確定義了到小數點下6位也就是微秒精度。 CREATE TABLE `services` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `start_time` timestamp(6) NOT NULL DEFAULT CURR...

Feb 25, 20232 min read

不要在 Production MySQL Server 上刪除資料表(< 8.0.23)

背景 前陣子團隊裡在討論,有用不到的 Table 要刪掉,是否要用一個月一次深夜停機的時段。我們團隊裡資深的同事表示他記得會有整個 DB 的 Lock 。我就想,照官方文件,Online DDL 應該不影響其他操作啊,而且也是針對該資料表。那平常的時間就可以刪啦? 不過又多做了一些搜尋,發現果然薑還是老的辣。。。 看到了這篇文章: Why you simply don't drop a huge InnoDB table in production... DROP table 會怎樣? 那篇文...

Sep 2, 20221 min read

炸蝦碎碎念

7 posts

我是在東京工作的Web後端軟體工程師,主要是用Java或Kotlin在Spring Boot上做內部的Microservice API。

私底下我喜歡健身、沖咖啡、和狗玩、還有玩一些電子DIY。

為什麼用這個平台: 想找個地方整理技術筆記心得,這裡可以用Markdown,我不太想用static generated的