๐Ÿ” https๋กœ React ๋กœ์ปฌ ํ…Œ์ŠคํŒ…ํ•˜๊ธฐ

๐Ÿงžโ€โ™‚๏ธ TL;DR

๋กœ์ปฌ์—์„œ https://dev.example.com์œผ๋กœ ํ…Œ์ŠคํŒ…ํ•˜๊ธฐ

  1. /etc/hosts์—์„œ ํ˜„์žฌ ip์™€ ๊ฐ€์งœ url์„ ๋งคํ•‘ํ•ด์ค€๋‹ค
  2. mkcert๋กœ ๊ฐ€์งœ url SSL ์ธ์ฆ์„œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค
  3. package.json์—์„œ npm start ์Šคํฌ๋ฆฝํŠธ์— SSL ์ธ์ฆ์„œ ์œ„์น˜๋ฅผ ์„ค์ •ํ•ด์ค€๋‹ค
  4. https://dev.example.com:3000 ์œผ๋กœ ์ ‘์†ํ•œ๋‹ค

2021๋…„ 1์›”์— ์—…๋ฐ์ดํŠธ๋œ Chrome์€(๋ฒ„์ „ M88) ๊ฐ™์€ ๋„๋ฉ”์ธ์˜ http ์‚ฌ์ดํŠธ์™€ https ์‚ฌ์ดํŠธ๋ฅผ cross-site๋กœ ์ทจ๊ธ‰ํ•˜๋„๋ก ์ •์ฑ…์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค. ์ด๋ฅผ Schemeful same-site ์ •์ฑ…์ด๋ผ๊ณ  ํ•˜๋Š”๋ฐ URL์—์„œ http, https ๋ถ€๋ถ„์„ scheme์ด๋ผ๊ณ  ๋ถˆ๋Ÿฌ์„œ ๊ทธ๋ ‡๋‹ค. (์˜ˆ: https://google.com ์—์„œ https ๋ถ€๋ถ„์ด scheme)

์ด์ „ ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ์—์„œ httpOnly, secure cookie๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์™€ refreshToken์„ ์ฃผ๊ณ  ๋ฐ›์•˜๋Š”๋ฐ, M88 ์—…๋ฐ์ดํŠธ๋กœ ์ธํ•ด ๋กœ์ปฌ์—์„œ ํ…Œ์ŠคํŒ…ํ•  ๋•Œ ์„œ๋ฒ„ API ๋„๋ฉ”์ธ๊ณผ ๊ฐ™์€ ๋„๋ฉ”์ธ์„ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ์„œ๋ฒ„ API๊ฐ€ https ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ํด๋ผ์ด์–ธํŠธ ๋กœ์ปฌ ํ™˜๊ฒฝ์€ http๋ฉด ์„œ๋ฒ„์—์„œ refreshToken cookie๋ฅผ ์ „๋‹ฌ๋ฐ›์ง€ ๋ชปํ–ˆ๋‹ค๋Š” ์—๋Ÿฌ๊ฐ€ ๋œฌ๋‹ค.

This Set-Cookie didn't specify a "SameSite" attribute and was defaulted to "SameSite=Lax", and was blocked because it came from a cross-site response which was not the response to a top-level navigation. This response is considered cross-site because the URL has a different scheme than the current site.

๋กœ์ปฌ ํ…Œ์ŠคํŒ…์—์„œ https๋ฅผ ์ ์šฉํ•ด ๋Œ€์‘ํ•ด๋ณด์ž.

๐Ÿšจ ์ฃผ์˜: ๋ชจ๋“  ์˜ˆ์ œ๋Š” mac์šฉ์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ๋‹ค. windows์™€ linux์šฉ์€ ์ฐพ๊ธฐ ์กฐ๊ณฐ ๊ท€์ฐฎ์•„์„œ... ์ง‘๋‹จ ์ง€์„ฑ๊ป˜์„œ ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์‹œ๋ฉด ์ถ”๊ฐ€ํ•˜๊ฒ ๋‹ค

๐Ÿ– ๋กœ์ปฌ์—์„œ https๋กœ ํ…Œ์ŠคํŒ…ํ•˜๊ธฐ

1. /etc/hosts์—์„œ ํ˜„์žฌ ip์™€ ๊ฐ€์งœ url์„ ๋งคํ•‘ํ•ด์ค€๋‹ค

1) ํ„ฐ๋ฏธ๋„์—์„œ ifconfig๋กœ ํ˜„์žฌ ip๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

$ ifconfig

ํ•˜์ด๋ผ์ดํŠธ๋œ 10.177.195.111์ด ip๋‹ค.

2) /etc/hosts ํŒŒ์ผ๋กœ ๋“ค์–ด๊ฐ€ ip์™€ dev.example.com์„ ๋งคํ•‘ํ•ด์ค„๊ฑฐ๋‹ค. ์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌํ•ด์ฃผ๋ฉด ๋ธŒ๋ผ์šฐ์ €์— dev.example.com url์„ ์ž…๋ ฅํ•ด ์ ‘์†ํ•˜๋ คํ•  ๋•Œ ๋‚ด ip์—์„œ ๋Œ์•„๊ฐ€๋Š” ์„œ๋ฒ„๋ฅผ ๋„์›Œ์ค€๋‹ค.

sudo vi /etc/hosts

Password ๋ฌผ์–ด๋ณด๋ฉด ์ปดํ“จํ„ฐ ๋น„๋ฒˆ์„ ์ ์–ด์ค€๋‹ค. (/etc/hosts ์ˆ˜์ •์€ ๋ฃจํŠธ๋งŒ ๊ฐ€๋Šฅํ•ด์„œ sudo๊ฐ€ ํ•„์š”ํ•˜๋‹ค)

# 
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost

// ๐Ÿ‘‡ ์–˜๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค
10.177.195.111     dev.example.com

/etc/hosts ํŒŒ์ผ์„ ์ด๋ ‡๊ฒŒ ์ˆ˜์ •ํ•ด์ฃผ๊ณ , esc ํ‚ค ๋ˆ„๋ฅด๊ณ  :x ์ž…๋ ฅํ•˜๊ณ  ์—”ํ„ฐํ•˜๋ฉด ํŒŒ์ผ ์ €์žฅ๋˜๊ณ  vim์—์„œ ๋‚˜์˜จ๋‹ค.

2. mkcert๋กœ ๊ฐ€์งœ url SSL ์ธ์ฆ์„œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค

mkcert๋Š” ๊ฐœ๋ฐœํ™˜๊ฒฝ์— SSL ์ธ์ฆ์„œ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค. ํ„ฐ๋ฏธ๋„์—์„œ brew๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋‹ค์šด๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

brew install mkcert

React ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฃจํŠธ ํด๋”๋กœ ๋“ค์–ด๊ฐ€ mkcert๋ฅผ ์‹คํ–‰ํ•˜๊ณ  example.com SSL ์ธ์ฆ์„œ๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

$ mkcert -install
$ mkcert "*.example.com" 127.0.0.1 ::1

๊ทธ๋Ÿผ ๋ฃจํŠธ ํด๋”์— _wildcard.example.com-key.pem _wildcard.example.com.pem ํŒŒ์ผ๋“ค์ด ์ƒ์„ฑ๋œ๋‹ค.

3. package.json์—์„œ npm start ์Šคํฌ๋ฆฝํŠธ์— SSL ์ธ์ฆ์„œ ์œ„์น˜๋ฅผ ์„ค์ •ํ•ด์ค€๋‹ค

package.json scripts์˜ start๋ฅผ ์ˆ˜์ •ํ•ด์ค€๋‹ค.


  "scripts": {
    ...,
    "start": "HTTPS=true SSL_CRT_FILE=_wildcard.example.com.pem SSL_KEY_FILE=_wildcard.example.com-key.pem HOST=0.0.0.0 start:react",
    ...

4. ๋!

ํ„ฐ๋ฏธ๋„์—์„œ React ์•ฑ์„ ์‹คํ–‰ํ•ด์ค€๋‹ค.

$ npm start

Chrome ๋ธŒ๋ผ์šฐ์ €์—์„œ https://dev.example.com:3000 ์œผ๋กœ ์ ‘์†ํ•œ๋‹ค. (๋˜๋Š” ๋‹ค๋ฅธ ํฌํŠธ์— ์—ด๋ ธ์„ ๊ฒฝ์šฐ 3000 ๋Œ€์‹  ํฌํŠธ ๋„˜๋ฒ„๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค)

โ›ฑ ๋ฒˆ์™ธ: localhost์— https ์ฒ˜๋ฆฌํ•˜๊ธฐ

ํ˜น์‹œ๋‚˜ ๊ฐ„๋‹จํ•˜๊ฒŒ localhost์—์„œ๋งŒ https ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด ์ ์–ด๋ดค๋‹ค.

1. mkcert๋กœ localhost SSL ์ธ์ฆ์„œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค

mkcert๋Š” ๊ฐœ๋ฐœํ™˜๊ฒฝ์— SSL ์ธ์ฆ์„œ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค. ํ„ฐ๋ฏธ๋„์—์„œ brew๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋‹ค์šด๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

brew install mkcert

React ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฃจํŠธ ํด๋”๋กœ ๋“ค์–ด๊ฐ€ mkcert๋ฅผ ์‹คํ–‰ํ•˜๊ณ  localhost SSL ์ธ์ฆ์„œ๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

$ mkcert -install
$ mkcert localhost 127.0.0.1 ::1

๊ทธ๋Ÿผ ๋ฃจํŠธ ํด๋”์— localhost-key.pem localhost.pem ํŒŒ์ผ๋“ค์ด ์ƒ์„ฑ๋œ๋‹ค.

2. package.json์—์„œ npm start ์Šคํฌ๋ฆฝํŠธ์— SSL ์ธ์ฆ์„œ ์œ„์น˜๋ฅผ ์„ค์ •ํ•ด์ค€๋‹ค

package.json scripts์˜ start๋ฅผ ์ˆ˜์ •ํ•ด์ค€๋‹ค.


  "scripts": {
    ...,
    "start": "HTTPS=true SSL_CRT_FILE=localhost.pem SSL_KEY_FILE=localhost-key.pem start:react",
    ...

3. ๋!

ํ„ฐ๋ฏธ๋„์—์„œ React ์•ฑ์„ ์‹คํ–‰ํ•ด์ค€๋‹ค.

$ npm start

Chrome ๋ธŒ๋ผ์šฐ์ €์—์„œ https://localhost:3000 ์œผ๋กœ ์ ‘์†ํ•œ๋‹ค.


์ฐธ๊ณ  ์ž๋ฃŒ

๐Ÿ™Œ parfumes๋‹˜์ด ๊ณต์œ ํ•ด์ค€ ๊ธ€: kakao tech ๋ธ”๋กœ๊ทธ ๊ธ€ "FE๊ฐœ๋ฐœ์ž์˜ ์„ฑ์žฅ ์Šคํ† ๋ฆฌ 06 : 2021๋…„ Chrome์˜ ์ƒˆ๋กœ์šด ๋ณ€ํ™” โ€“ Schemeful same-site์„ ๋Œ€์‘ํ•˜์ž"
๐Ÿ™Œ esinx๋‹˜์ด ๊ณต์œ ํ•ด์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ: mkcert github ํŽ˜์ด์ง€
โœ๏ธ Flavio Copes ๋ธ”๋กœ๊ทธ ๊ธ€ "How to configure HTTPS in a React app on localhost"
โœ๏ธ Google web.dev ๊ธ€ "Schemeful Same-Site"

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ