CORS

  • CORS ๋ž€

    • Cross-Origin Resource Sharing์˜ ์ค„์ž„๋ง์ด๋‹ค. ๋‹จ์–ด ๊ทธ๋Œ€๋กœ ๋ณด๋ฉด ๊ต์ฐจ ์ถœ์ฒ˜ ์ž์› ๊ณต์œ ๋ผ๋Š” ์˜๋ฏธ์ธ๋ฐ, ์ข€ ๋” ํ’€์–ด๋ณด๋ฉด ์ถœ์ฒ˜๊ฐ€ ๋‹ค๋ฅธ ์ž์›์„ ๊ณต์œ ํ•œ๋‹ค๋Š” ๊ฑธ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

    • CORS๋Š” ๋™์ผ ์ถœ์ฒ˜์ •์ฑ…(Same-origin policy, ์ดํ•˜ SOP) ๋•Œ๋ฌธ์— ๋‚˜์™”๋‹ค. ๊ทธ๋Ÿผ ๋จผ์ € ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์— ๋Œ€ํ•ด์„œ ๋จผ์ € ์•Œ์•„๋ณด์ž.

    • ๋™์ผ์ถœ์ฒ˜ ์ •์ฑ…(Same-origin policy)

      • ํ•œ ์ถœ์ฒ˜ ์—์„œ ๋กœ๋“œํ•œ ๋ฌธ์„œ ๋˜๋Š” ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค์™€ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œํ•œํ•˜๋Š” ์ค‘์š”ํ•œ ๋ณด์•ˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค.

      • ๋ผ๊ณ  ์ด๊ณณ์— ์„œ์ˆ ๋ผ ์žˆ๋‹ค.

      • ์œ„์˜ ๋ฌธ์žฅ์„ ๋ณด๋ฉด, ํ•œ ์ถœ์ฒ˜์—์„œ ๋กœ๋“œ๋œ ๋ฆฌ์†Œ์Šค๋Š” ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค์™€ ์ƒํ˜ธ์ž‘์šฉ ํ•  ์ˆ˜ ์—†๊ฒŒ ํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์™œ ๊ทธ๋žฌ์„๊นŒ? ๋ณด์•ˆ ๋•Œ๋ฌธ์ด๋ผ๋Š” ๊ฒƒ์„ ์‰ฝ๊ฒŒ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ๋‹ค.

      • ์˜ˆ๋ฅผ ๋“ค์–ด์„œ ๋‚˜๋Š” A๋ผ๋Š” ์น˜ํ‚จ์ง‘์— ์ „ํ™”ํ•ด์„œ ์–‘๋… 1๋งˆ๋ฆฌ๋ฅผ ์‹œ์ผฐ๋Š”๋ฐ, A๊ฐ€ B๋ผ๋Š” ๊ฐ€๊ฒŒ์— ํ•˜์ฒญ์„ ์ฃผ์–ด์„œ(redirect?) B์น˜ํ‚จ์ง‘์—์„œ ์–‘๋…์น˜ํ‚จ์„ ๋ณด๋‚ด์˜จ ๊ฒƒ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ๋œ ๊ฒฝ์šฐ, ๊ฒฐ๊ตญ์—๋Š” ๋‚ด๊ฐ€ ์›ํ•˜๋˜ ์น˜ํ‚จ๋ง›์ด ์•„๋‹ ์ˆ˜๋„ ์žˆ๊ณ  ๋‚˜์•„๊ฐ€ B์—์„œ ๋‚ด ์น˜ํ‚จ์— ๋ฌด์Šจ ์ง“์„ ํ•˜๋Š”์ง€ ๋‚˜๋Š” ์ „ํ˜€ ๋ชจ๋ฅธ ์ฑ„๋กœ ์น˜ํ‚จ์„ ๋จน์–ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.(๋ฌผ๋ก  ์น˜ํ‚จ์€ ํ•ญ์ƒ ๋ง›์žˆ์„ ๊ฑฐ๋ผ ์ƒ๊ฐํ•œ๋‹ค.)

      • ์ž ์žฌ์ ์ธ ์•…์„ฑ ๋ฌธ์„œ๋ฅผ ๊ฒฉ๋ฆฌํ•˜๊ณ  ๊ณต๊ฒฉ์„ ์˜ˆ๋ฐฉํ•œ๋‹ค๋Š” ์ทจ์ง€์ธ ๊ฒƒ์ด๋‹ค. ์ข€ ๋” ์ง„์ง€ํ•œ ์˜ˆ๋กœ, ์ธํ„ฐ๋„ท์˜ ์•…์˜์ ์ธ ์›น์‚ฌ์ดํŠธ๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์—์„œ JS๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ํƒ€์‚ฌ ์›น๋ฉ”์ผ ์„œ๋น„์Šค(์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•œ ์„œ๋น„์Šค) ๋˜๋Š” ํšŒ์‚ฌ ์ธํŠธ๋ผ๋„ท์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ์ผ์ด ์žˆ์„ ์ˆ˜๋„ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ ๋™์ผ์ถœ์ฒ˜๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— client์—์„œ ๊ฑฐ๋ถ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

      • ๋™์ผ ์ถœ์ฒ˜๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ธฐ์ค€์€ host url์„ ๊ธฐ์ค€์œผ๋กœ ํ•˜๋Š”๋ฐ, ํ”„๋กœํ† ์ฝœ, ํฌํŠธ, ํ˜ธ์ŠคํŠธ๊ฐ€ ๋ชจ๋‘ ๋™์ผํ•ด์•ผ ๊ฐ™์€ url์ด๋ผ๊ณ  ์ธ์ •ํ•œ๋‹ค.

    • CORS์˜ ํ•„์š”์„ฑ

      • ์ธํ„ฐ๋„ท์ด ๋ฐœ๋‹ฌํ•˜๋ฉด์„œ ๊ฐ application์˜ ๋น„์ฆˆ๋‹ˆ์Šค๊ฐ€ ๋ณต์žกํ•ด์ง€๊ณ , ํƒ€ ํ”„๋กœ๊ทธ๋žจ๊ณผ์˜ ์—ฐ๊ด€์„ฑ์ด ๋†’์•„์ง€๋ฉด์„œ ์„œ๋กœ ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•ด์•ผ ํ•  ์ผ์ด ๋งŽ์•„์กŒ๋‹ค.

      • F/E์™€ B/E์˜ ๋ถ„๋ฆฌ๋กœ ์ธํ•ด์„œ ์„œ๋ฒ„๊ฐ€ ๋‚˜๋‰˜๊ฒŒ ๋œ๋‹ค. Front ์„œ๋ฒ„๋Š” ๋ Œ๋”๋ง์— ์‚ฌ์šฉ๋˜๊ณ , Backend ์„œ๋ฒ„๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋๋‹ค. ํด๋ผ์ด์–ธํŠธ๋Š” ์ด ๋‘ ๊ฐ€์ง€ ์„œ๋ฒ„์— ๊ฐ๊ธฐ ๋‹ค๋ฅธ ์š”์ฒญ์„ ๋ณด๋‚ด์•ผํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฒ˜๋ฆฌ์— ํ•œ๊ณ„๊ฐ€ ์ƒ๊ฒผ๋‹ค.

    • ์ด๋Ÿฌํ•œ ํ•„์š”์„ฑ์— ๋”ฐ๋ผ CORS๋ฅผ ํ—ˆ์šฉํ•˜๊ฒŒ ๋๋Š”๋ฐ, ์ด ์ž‘์—…์€ HTTP ํ—ค๋”๋ฅผ ์กฐ์ž‘ํ•จ์œผ๋กœ ์ด๋ค„์ง„๋‹ค.

      • Access-Control-Allow-Origin

        • ์ง์—ญํ•ด๋ณด๋ฉด ์ด ์ถœ์ฒ˜์˜ ์ ‘๊ทผ ํ—ˆ์šฉ์„ ํ†ต์ œํ•œ๋‹ค๋Š” ๋œป์ด๊ฒ ๋‹ค. HTTP ํ—ค๋”์— ์œ„์˜ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ๊ทธ ๊ฐ’์œผ๋กœ url์„ ๋„ฃ์œผ๋ฉด ํ•ด๋‹น url์€ client์—์„œ ์ถœ์ฒ˜๊ฐ€ ๋‹ค๋ฅด๋”๋ผ๋„ ํ—ˆ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

    • JSONP

      • ๋ธŒ๋ผ์šฐ์ €์—์„œ SOP๋ฌธ์ œ๋ฅผ ํšŒํ”ผํ•˜๊ธฐ ์œ„ํ•ด์„œ <script>ํƒœ๊ทธ๋ฅผ ์ด์šฉํ•ด ๊ผผ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ JSON ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค. HTML์˜ <script> ์š”์†Œ๋กœ๋ถ€ํ„ฐ ์š”์ฒญ๋˜๋Š” ํ˜ธ์ถœ์—๋Š” ๋ณด์•ˆ์ƒ ์ •์ฑ…์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ์ด์šฉํ•œ ์šฐํšŒ ๋ฐฉ๋ฒ•์ด๋‹ค.

      • JSONP๋Š” GET๋ฐฉ์‹๋งŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ ์„œ๋ฒ„์—์„œ ํ•จ๊ป˜ JSONP๋ฅผ ์ง€์›ํ•ด์ค˜์•ผ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ œ์•ฝ์ด ์žˆ๋‹ค.

  • @CrossOrigin

    • Java์˜ Servlet๊ธฐ๋ฐ˜ HTTPํ†ต์‹ ์— ์‚ฌ์šฉ๋˜๋Š” HttpServletResponseํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ํ—ค๋”๊ฐ’์— Access-Control-Allow-Origin๋ฅผ ์„ค์ •ํ•ด์ฃผ๋ฉด ์ ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

    • Spring์—์„œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋” ํŽธ๋ฆฌํ•˜๊ฒŒ @CrossOrigin์„ ๋ฉ”์„œ๋“œ๋‚˜ ํด๋ž˜์Šค(์ƒํ™ฉ์— ๋งž๋Š” ์Šค์ฝ”ํ”„)์— ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜๋ฉด, CORS๋ฅผ ํ—ˆ์šฉํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค.

    • @CrossOrigin๋งŒ ๋ถ™์ด๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ๋„๋ฉ”์ธ๊ณผ, ๋ชจ๋“  ์š”์ฒญ๋ฐฉ์‹์— ๋Œ€ํ•ด ํ—ˆ์šฉํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค.

    • @CrossOrigin์˜ ์š”์†Œ ์ค‘์˜ origins์˜ ๊ฐ’์œผ๋กœ url์„ ์ถ”๊ฐ€ํ•˜๋ฉด, ํ—ˆ์šฉํ•  ๋„๋ฉ”์ธ์„ ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ ๋ฐฉ์‹์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

    @CrossOrigin
    @GetMapping
    public List<PostDto> list() {
        return List.of(
                new PostDto("1", "title1", "body1"),
                new PostDto("2", "title2", "body2"),
                new PostDto("3", "title3", "body3")
        );
    }
    
    @CrossOrigin(origins = "http://example.com/", "http://localhost:8080)
    @GetMapping
    public List<PostDto> list() {
        return List.of(
                new PostDto("1", "title1", "body1"),
                new PostDto("2", "title2", "body2"),
                new PostDto("3", "title3", "body3")
        );
    }

Last updated