[Network] CORS, HTTP, REST API
Categories: Network
Tags: CS, Network, ๊ฐ๋ ์ ๋ฆฌ
๐ ๊ฐ์ธ์ ์ธ ๊ณต๊ฐ์ผ๋ก ๊ณต๋ถ๋ฅผ ๊ธฐ๋กํ๊ณ ๋ณต์ตํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๋ธ๋ก๊ทธ์
๋๋ค.
์ ํํ์ง ์์ ์ ๋ณด๊ฐ ์์ ์ ์์ผ๋ ์ฐธ๊ณ ๋ฐ๋๋๋ค :๐ธ
[ํ๋ฆฐ ๋ด์ฉ์ ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์๋ฉด ๋ณต๋ฐ์ผ์ค๊ฑฐ์์]
SSR, CSR
- SSR (Server Side Rendering)
- Javascript ๊ฐ ์น ํ์ด์ง๋ฅผ ์๋ฒ์์ ๋ ๋๋ง (=์กฐ๋ฆฝ ์๋ฃ๋ ๊ฐ๊ตฌ๊ฐ ๋ฐฐ์ก๋๋ ๊ฒ๊ณผ ๋น์ท)
- ๋ค์ด๋ฒ ๋ธ๋ก๊ทธ- 2020๋ ์ ๋์ , ๊ฒ์์์ง ์ต์ ํ๋ฅผ ์ํด ์ ์ฒด๋ฅผ SSR๋ก ๋ณ๊ฒฝ
- CSR (Client Side Rendering)
- โ SSR
- SSR์ด ์๋ฒ ์ธก์์ Javascript ๊ฐ ํ์ด์ง๋ฅผ ๋ ๋๋งํ๋ค๋ฉด, CSR์ ํด๋ผ์ด์ธํธ์์ Javascript ๊ฐ ํ์ด์ง๋ฅผ ๋ ๋๋ง (=๊ฐ๊ตฌ์ ๋ถํ์ด ๋๋ ์ ์ด์ก์ด ์ฝ๊ฒ ๋ฐฐ์ก๋๋ ๊ฒ๊ณผ ๋น์ท)
- ์น ํ์ด์ง์ ๊ณจ๊ฒฉ์ด ๋ ๋จ์ผ ํ์ด์ง๋ฅผ ํด๋ผ์ด์ธํธ์๊ฒ ๋ณด๋ ์ด๋ ์๋ฒ๋ ์น ํ์ด์ง์ ํจ๊ป JavaScript ํ์ผ์ ๋ณด๋
- ๊ฒ์์์ง ์ต์ ํ - 0์
- CSR์์๋ SSR๊ณผ ๋ค๋ฅด๊ฒ, ์๋ฒ๊ฐ ์น ํ์ด์ง๋ฅผ ๋ค์ ๋ณด๋ด์ง ์์ต๋๋ค
- ์์ด์ ์ค ๊ธฐ์ ์ ์ฌ์ฉํ๋ ์ด์ ์ด ์์. โ ์ฌ์ฉ์์ ํธ๋ฆฌ์ฑ.
- ์์
- Agoda - ๊ฒ์์์ง ๋ ธ์ถ ๋์ ์ ๋ง์ผํ ์ผ๋ก ๋ ธ์ถ
CORS
- Cross-Origin Resource Sharing, ๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์
- ์๋ก ๋ค๋ฅธ Origin์ ๊ฐ์ง Application์ด ์๋ก์ Resource์ ์ ๊ทผํ ์ ์๋๋ก ํด์ค
โ
์๋ก ๋ค๋ฅธ Origin์ ๊ฐ์ง ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์์ ๊ณต์ ํ ๋ ๋ฌธ์ ๊ฐ ์๊น โ ๋ง์ฝ์ ๋ค๋ฅธ ์ฌ์ฉ์๊ฐ ๋ด ์ฌ์ดํธ์ ์ด๋ฏธ์ง๋ฅผ ๋งํฌ๋ก ์ ๊ทผ - ๋ค๋ฅธ๋ฐ์ ์ฌ์ฉ ์ ํ ๋๋ง๋ค ๋ฆฌ์์ค๊ฐ ๋ค๊ฒ ๋จ โ ํด๋ผ์ด์ธํธ(๋ธ๋ผ์ฐ์ )์ ์๋ฒ ๊ฐ์ HTTP๋ฅผ ์์ฒญ ์ ์๋ฒ๊ฐ HTTP์ ๋๋ ํ์ฉ ๊ฐ์ ๊ฑธ ๋ด์์ ๊ฐ์ด ๋ณด๋ด๋๋ฐ ๋ง์ฝ์ Origin์ด ๋ค๋ฅผ ๊ฒฝ์ฐ CORS ์ค๋ฅ ๋ฐ์
- ๋ธ๋ผ์ฐ์ ๊ฐ ๋ ๋ค naver.com ์ผ ๊ฒฝ์ฐ ๋ฐ์ํ์ง ์๊ณ naver.com ๊ฐ kakao.com ์ ์์ฒญํ ๊ฒฝ์ฐ ๋ฐ์
- CORS๋ ๋ธ๋ผ์ฐ์ ์์ ๋ฐ์, ํน์ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฌ์ฉํ๋ค๊ณ CORS๊ฐ ์ฌ๋ผ์ง์ง ์์.
- CORS ์ค์ ์ ์๋ฒ์์ ํจ.
- CORS ์ ์ฒด ํ์ฉํ๋ฉด ์๋จ โ ์? โ ๋ณด์์ทจ์ฝ์ ์ ๋ ธ๋ฆฐ ๊ณต๊ฒฉ
์ถ์ฒ(Origin)๋?
-
์ถ์ฒ(Origin)๋ URL ๊ตฌ์กฐ์์ ์ดํด๋ณธ Protocal, Host, Port๋ฅผ ํฉ์น ๊ฒ
-
์ถ์ฒ๋ฅผ ์๊ณ ์ถ์ ์ฌ์ดํธ์์ F12 ๋๋ฅด๊ณ ์ฝ์ ์ฐฝ์ย
location.origin
๋ฅผ ์คํํ๋ฉด ์ถ์ฒ๋ฅผ ํ์ธ -
๊ฐ์ ์ถ์ฒ vs ๋ค๋ฅธ ์ถ์ฒ
ํ์ฌ ์นํ์ด์ง์ ์ฃผ์๊ฐ https://quokkavely.github.io/tech/
์ผ๋
URL | ๊ฒฐ๊ณผ | ์ด์ |
---|---|---|
https://quokkavely.github.io/about | ๊ฐ์ ์ถ์ฒ | Protocol, Host, Port ๋์ผ |
https://quokkavely.github.io/about?q=work | ๊ฐ์ ์ถ์ฒ | Protocol, Host, Port ๋์ผ |
https://quokkavely.github.io/about#work | ๊ฐ์ ์ถ์ฒ | Protocol, Host, Port ๋์ผ |
http://quokkavely.github.io | ๋ค๋ฅธ ์ถ์ฒ | Protocol ๋ค๋ฆ |
https://quokkavely.github.io:81/about | ๋ค๋ฅธ ์ถ์ฒ | Port ๋ค๋ฆ |
https://quokkavely.heroku.com | ๋ค๋ฅธ ์ถ์ฒ | Host ๋ค๋ฆ |
๋์ผ ์ถ์ฒ ์ ์ฑ (Same-Origin Policy)
-
๋ธ๋ผ์ฐ์ ๊ฐ ๋์ผ ์ถ์ฒ ์ ์ฑ (Same-Origin Policy, SOP)๋ฅผ ์ง์ผ์ ๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค ์ ๊ทผ์ ๊ธ์งํจ
์๊ณ ๋ค์์ ๊ฐ๋ฐ์๋ชจ๋์ ๋ค์ด๊ฐ๋ฉด cors์ค์ ๋ณผ ์ ์์
-
์ฅ์
- XSS๋ย XSRFย ๋ฑ์ ๋ณด์ ์ทจ์ฝ์ ์ ๋ ธ๋ฆฐ ๊ณต๊ฒฉ์ ๋ฐฉ์ด
- ์ธ๋ถ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ SOP์ ์์ธ ์กฐํญ์ด CORS
CORS ๋์์๋ฆฌ
Simple request
โ
- ๋ฐ๋ก ์์ฒญํด์ ๋ฐ๋ก ์๋ต์ ๋ฐ๋ ๊ฒ
์๋ ์กฐ๊ฑด์ ํด๋น๋๋ ๊ฒฝ์ฐ์๋ง ๊ฐ๋ฅํจ. - 1~3 ๋ฒ์ ์กฐ๊ฑด์ ๋ชจ๋ ์ถฉ์กฑํด์ผ ํจ
- ์์ฒญ ๋ฉ์๋(method) : 3๊ฐ ์ค ํ๋์ ํด๋น ๋์ด์ผ ํจ,
- GET
- HEAD
- POST
- ํค๋
- Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width ๋ฅผ ์ ์ธํ ํค๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๋จ
- Content-Type ํค๋
- application/x-www-form-urlencoded, multipart/form-data, text/plain ์ค ํ๋๋ฅผ ์ฌ์ฉ
- ์๋ง JSON ํ์ ์ ์ฌ์ฉํ ๊ฒฝ์ฐ Simple request๋ ์ฌ์ฉ ๋ชปํจ
Preflight request
- Preflight ์์ฒญ์ ์ค์ ๋ฆฌ์์ค๋ฅผ ์์ฒญํ๊ธฐ ์ ์ย
OPTIONS
๋ผ๋ ๋ฉ์๋๋ฅผ ํตํด ์ค์ ์์ฒญ์ ์ ์กํ ์ง ํ๋จ OPTIONS
ย ๋ฉ์๋๋ก ์๋ฒ์ ์๋น ์์ฒญ์ ๋จผ์ ๋ณด๋ด๊ณ , ์๋ฒ๋ ์ด ์๋น ์์ฒญ์ ๋ํ ์๋ต์ผ๋กยAccess-Control-Allow-Origin
ย ํค๋๋ฅผ ํฌํจํ ์๋ต์ ๋ธ๋ผ์ฐ์ ์ ๋ณด๋- ๋ธ๋ผ์ฐ์ ๋ ๋จ์ ์์ฒญ๊ณผ ๋์ผํ๊ฒย
Access-Control-Allow-Origin
ย ํค๋๋ฅผ ํ์ธํด์ CORS ๋์์ ์ํํ ์ง ํ๋จ
CORS ์๋ฌ ํด๊ฒฐ ๋ฐฉ๋ฒ
- ์์์ ์ด์ผ๊ธฐ ํ CORS ๋์ ์๋ฆฌ๋ฅผ ๋ณด๋ฉด, ์๋ฒ์์ย
Access-Control-Allow-Origin
ย ํค๋๋ฅผ ํฌํจํ ์๋ต์ ๋ธ๋ผ์ฐ์ ์ ๋ณด๋ด๋ ๋ฐฉ์์ผ๋ก CORS ์๋ฌ๋ฅผ ํด๊ฒฐ๊ฐ๋ฅ. - ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๊ฐ CORS ์๋ฌ๋ฅผ ํ์ธํ๋ค๋ฉด, ์๋ฒ์ย
Access-Control-Allow-Origin
ย ๋ฑ CORS๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ์๋ต ํค๋๋ฅผ ํฌํจํด ๋ฌ๋ผ๊ณ ์์ฒญํด์ผ ํจ.
HTTP ์์ฒญ ํค๋
-
CORS๋ฅผ ์ํด์, ๋ธ๋ผ์ฐ์ ์์ ์๋ฒ๋ก ์์ฒญํ๋ ํค๋
-
์์ฒญ ํค๋๋ค์ ๋ณ๋๋ก ๋ช ์ํด ์ฃผ์ง ์์๋ ๋ธ๋ผ์ฐ์ ์์ย
OPTIONS
ย ์์ฒญ์ ์ถ๊ฐ -
OPTIONSโ ์ ๋ ๊น๋จน์ผ๋ฉด ์๋จ.
Origin: <origin>
Origin
ย ํค๋๋ ์์ฒญํ๋ ๋์์ ์ถ์ฒ๋ฅผ ๋ํ๋- API๋ฅผ ํธ์ถํ๋ ํ์ด์ง์ ์ถ์ฒ ๊ฐ์ด ์ ์ฅ๋ฉ๋๋ค.
Access-Control-Request-Method: <method>
Access-Control-Request-Method
ย ํค๋๋ ์ค์ ์์ฒญ์ด ์ด๋ค HTTP ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋์ง ์๋ฒ์ ์๋ ค์ฃผ๊ธฐ ์ํด ์ฌ์ฉ
Access-Control-Request-Headers: <field-name>[, <field-name>]
Access-Control-Request-Headers
ย ํค๋๋ ๋ธ๋ผ์ฐ์ ์์ ๋ณด๋ด๋ ์ปค์คํ ํค๋ ์ด๋ฆ์ ์๋ฒ์ ์๋ ค์ฃผ๊ธฐ ์ํด ์ฌ์ฉ
HTTP ์๋ตํค๋
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉํ๋ฉด ๊ฐ๋จํ๊ฒ CORS๋ฅผ ํด๊ฒฐ ํ ์ ์์
์๋ตํค๋ ์ข ๋ฅ
HTTP ์๋ต ํค๋ | description | Syntax | ๋น๊ณ |
---|---|---|---|
Access-Control-Allow-Origin: <origin>|* |
ํค๋์ ์์ฑ๋ ์ถ์ฒ๋ง ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฆฌ์์ค๋ฅผ ์ ๊ทผํ ์ ์๋๋ก ํ์ฉ | Access-Control-Allow-Origin: * Access-Control-Allow-Origin: <origin> Access-Control-Allow-Origin: null |
ย |
Access-Control-Allow-Methods: <method>[, <method>]* |
๋ฆฌ์์ค์ ์ ๊ทผํ ๋ ํ์ฉ๋๋ ๋ฉ์๋๋ฅผ ์ง์ | Access-Control-Allow-Methods:, POST, GET, OPTIONS,<br/ > Access-Control-Allow-Methods: * |
preflight request ๋ํ ์๋ต(Access-Control-Request-Method) |
Access-Control-Expose-Headers | cross-origin request์ ๋ํ ์๋ต์ผ๋ก ๋ธ๋ผ์ฐ์ ์์ ์คํ ์ค์ธ ์คํฌ๋ฆฝํธ๊ฐ ์ฌ์ฉํ ์ ์๋ ์๋ต ํค๋๋ฅผ ์ง์ ๊ฐ๋ฅ | Access-Control-Expose-Headers: [<header-name>[, <header-name>]*] , Access-Control-Expose-Headers: * |
cross-origin request์ ๋ํ ์๋ต |
Access-Control-Allow-Headers | ์ค์ ์์ฒญ๋ ์ฌ์ฉํ ์ ์๋ HTTP ํค๋์ ๋ชฉ๋ก์ ๋์ด | Access-Control-Allow-Headers: <header-name>[, <header-name>]* Access-Control-Allow-Headers: * |
preflight request์ ์๋ต์ ์ฌ์ฉ๋๋ ํค๋, ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์์ฒญํ ๋ ์ด๋ค ํค๋๋ค์ ํฌํจํ ์ ์๋์ง ์๋ฒ๊ฐ ๋ช ์ํ๋ ๊ฒ. |
Access-Control-Max-Age | preflight request์ ๊ฒฐ๊ณผ๋ฅผ ์ผ๋ง๋ ์ค๋ ์บ์ํ ์ ์๋์ง๋ฅผ ๋ํ๋ | Access-Control-Max-Age: <delta-seconds> |
preflight request์ ๊ฒฐ๊ณผ(์ฆ, Access-Control-Allow-Methods ๋ฐ Access-Control-Allow-Headers ํค๋์ ํฌํจ๋ ์ ๋ณด) |
Access-Control-Allow-Credentials:true | Request.credentials๊ฐ include์ผ๋, ๋ธ๋ผ์ฐ์ ๋ค์ด ์๋ต์ ํ๋กํธ์๋ ์๋ฐ์คํธ๋ฆฝํธ ์ฝ๋์ ๋ ธ์ถํ ์ง์ ๋ํด ์๋ ค | Access-Control-Allow-Credentials: true, false์ผ ๊ฒฝ์ฐ ํค๋ ์๋ต | Access-Control-Allow-Credentials ๊ฐ์ด true ์ผ ๊ฒฝ์ฐ์๋ง ๋ธ๋ผ์ฐ์ ๋ค์ ํ๋กํธ์๋ ์๋ฐ์คํธ๋ฆฝํธ์ ์๋ต์ ๋ ธ์ถํจ |
-
Access-Control-Allow-Origin: <origin> |*
1.1 ํค๋์ ์์ฑ๋ ์ถ์ฒ๋ง ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฆฌ์์ค๋ฅผ ์ ๊ทผํ ์ ์๋๋ก ํ์ฉ
1.2 ์ฌ์ฉ ๋ฐฉ๋ฒ
- Access-Control-Allow-Origin: https://quokkavely.github.io
- https://quokkavely.github.ioย ํ์ด์ง์์ ๋ธ๋ผ์ฐ์ ๋ ์๋ฒ ์๋ต์ผ๋ก ์จ ๋ฆฌ์์ค๋ฅผ ์ ๊ทผํ ์ ์์
- Access-Control-Allow-Origin: * : *(์์ผ๋์นด๋)๊ฐ ์์ฑ๋์๋ค๋ฉด ๋ธ๋ผ์ฐ์ ๋ ์ถ์ฒ์ ์๊ด์์ด ๋ชจ๋ ๋ฆฌ์์ค์ ์ ๊ทผ ๊ฐ๋ฅ
1.3 ์์
1 2 3 4 5
fetch('http://localhost:3001/cors', { method: 'PUT', }).then(function(response) { }).catch(function(error) { })
Access-Control-Allow-Origin
ย ํค๋๋ฅผ ์ฒ๋ฆฌํ์ง ์์ ์๋ฒ์ API ํธ์ถ ์ ์๋ฌ ๋ฐ์ ํจ.
-
Access-Control-Allow-Methods: <method>[, <method>]
2.1 ๋ฆฌ์์ค ์ ๊ทผ์ ํ์ฉํ๋ HTTP ๋ฉ์๋๋ฅผ ์ง์ ํด ์ฃผ๋ ํค๋
2.2 Access-Control-Allow-Methodsย ํค๋์ย GET,ย PUT,ย POST,ย DELETEย ๋ฑ์ HTTP ๋ฉ์๋๋ฅผย ,๋ก ๊ตฌ๋ถํ์ฌ ๋๊ฒจ์ค
Ex)
Access-Control-Allow-Methods: GET, PUT
2.3 ์์
1 2 3 4 5
fetch('http://localhost:3001/cors', { method: 'PUT', }).then(function(response) { }).catch(function(error) { })
2.4
Access-Control-Allow-Methods
ย ํค๋๋ฅผ ์ฒ๋ฆฌํ์ง ์์ ์๋ฒ์ API๋ฅผ ํธ์ถโ ์๋ฌ ๋ฐ์,์๋ต ํค๋๋ฅผ ์ถ๊ฐํด์ฃผ์ด์ผ ํจ.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@RestController public class CorsController { @CrossOrigin(origins = "*", methods = {RequestMethod.OPTIONS, RequestMethod.PUT}) @RequestMapping(value = "/cors", method = RequestMethod.OPTIONS) public ResponseEntity<?> handleOptionsRequest() { return ResponseEntity.ok().build(); } @CrossOrigin(origins = "*", methods = {RequestMethod.OPTIONS, RequestMethod.PUT}) @RequestMapping(value = "/cors", method = RequestMethod.PUT) public ResponseEntity<?> handlePutRequest() { return ResponseEntity.ok().build(); } }
Access-Control-Allow-Origin
๋ย*
๋ก ๋ชจ๋ ์ถ์ฒ๋ฅผ ํ์ฉํ ์ํ์ด๊ณ , ๋ธ๋ผ์ฐ์ ์ ์์ฒญ ํค๋์ ํฌํจ๋ยAccess-Control-Request-Method
ย ํค๋ ๊ฐ์ ๊ทธ๋๋กยAccess-Control-Allow-Methods
ย ํค๋์ ์ถ๊ฐ -
Access-Control-Expose-Headers:
[, ]* 3.1
Access-Control-Allow-Headers
ํค๋๋ ํด๋ผ์ด์ธํธ๊ฐ ์ค์ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ ์ ์๋ฒ์ ๋ณด๋ด๋ ์ฌ์ ์์ฒญ(preflight request)์์ ์ฌ์ฉ3.2 ์ด ํค๋๋ ์๋ฒ๊ฐ ํ์ฉํ๋ ์์ฒญ ํค๋์ ๋ชฉ๋ก์ ์ง์ = ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์์ฒญํ ๋ ์ด๋ค ํค๋๋ค์ ํฌํจํ ์ ์๋์ง ์๋ฒ๊ฐ ๋ช ์
3.3 ์ฌ์ฉ๋ฐฉ๋ฒ :
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
3.4 ์์
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
@RestController public class CorsController { @RequestMapping(value = "/cors", method = RequestMethod.OPTIONS) public ResponseEntity<?> handleOptionsRequest(@RequestHeader("Access-Control-Request-Method") String requestMethod) { HttpHeaders headers = new HttpHeaders(); headers.set("Access-Control-Allow-Origin", "*"); headers.set("Access-Control-Allow-Methods", requestMethod); return ResponseEntity.ok().headers(headers).build(); } @RequestMapping(value = "/cors", method = RequestMethod.PUT) public ResponseEntity<?> handlePutRequest() { HttpHeaders headers = new HttpHeaders(); headers.set("Access-Control-Allow-Origin", "*"); headers.set("Access-Control-Expose-Headers", "X-Custom-Beomy"); headers.set("X-Custom-Beomy", "Bemoy"); return ResponseEntity.ok().headers(headers).build(); } }
3.4.1. ์๋ฒ์์
Access-Control-Expose-Headers
ย ํค๋์ยX-Custom-Beomy
๋ฅผ ์ถ๊ฐํด ์ฃผ๊ณ ,ยX-Custom-Beomy
ย ํค๋์ ๊ฐ์ ๋ด์ ์๋ต์ ํ๋ฉด3.4.2 ๋ธ๋ผ์ฐ์ ์์๋ ์๋์ฝ๋๋ฅผ ์คํํด์
X-Custom-Beomy
ย ํค๋ ๊ฐ์ ๊ฐ์ ธ์ฌ ์ ์๊ฒ ๋จ1 2 3 4 5 6 7 8
```java fetch('http://localhost:3001/cors', { method: 'PUT', }).then(function(response) { console.log(response.headers.get('X-Custom-Beomy')) // Beomy }).catch(function(error) { }) ```
3.4.3. ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ ๊ทผํ ํค๋๋ฅผ ๋ช ์ํด ์ฃผ์ง ์์ผ๋ฉด, ์๋ฐ์คํฌ๋ฆฝํธ์์ย
X-Custom-Beomy
ย ํค๋ ๊ฐ์ยundefined
-
Access-Control-Allow-Headers:
[, ]* 4.1 ๋ธ๋ผ์ฐ์ ์์ ๋ณด๋ด๋ ์์ฒญ ํค๋์ ํฌํจ๋ย
Access-Control-Request-Headers
ย ํค๋์ ๋ํ ์๋ต ๊ฒฐ๊ณผ4.2 ์ด ํค๋๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ฒ๋ ์ถ๊ฐ ํค๋๋ฅผ ํด๋ผ์ด์ธํธ์ ๋ ธ์ถ๊ฐ๋ฅ
4.3 ์ฌ์ฉ๋ฐฉ๋ฒ
4.4 ์์
-
์๋ฐ์คํฌ๋ฆฝํธ์์ ์ปค์คํ ํค๋๋ฅผ ์๋ฒ์ ์ ๋ฌํ๊ฒ ๋๋ฉด,ย
OPTIONS
ย ์์ฒญ ํค๋์ยAccess-Control-Request-Headers
ย ํค๋์ ์ปค์คํ ํค๋ ์ด๋ฆ์ด ์ถ๊ฐ๋ฉ๋๋ค. ์๋ฒ์์๋ยAccess-Control-Request-Headers
์ ์์ฑ๋ ๊ฐ์ ๋ณด๊ณ ยAccess-Control-Allow-Headers
ย ์๋ต ํค๋์ ์ปค์คํ ํค๋ ์ด๋ฆ์ ๋ช ์ํด ์ฃผ์ด์ผ ํฉ๋๋ค. -
Access-Control-Allow-Headers: X-Custom-Request
-
์๋ ์ฝ๋๋ฅผ ๋ธ๋ผ์ฐ์ ์์ ์คํํ์ฌ,ย
Access-Control-Allow-Headers
ย ์ฒ๋ฆฌ๋์ง ์์ API๋ฅผ ํธ์ถํ๊ฒ ๋๋ฉด,1 2 3 4 5 6 7 8
fetch('http://localhost:3001/cors', { method: 'PUT', headers: { 'X-Custom-Request': 'Beomy', } }).then(function(response) { }).catch(function(error) { })
-
์๋์ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์
-
์๋ตํค๋ ์ถ๊ฐ ํด์ค์ผํจ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
@RestController public class CorsController { @RequestMapping(value = "/cors", method = RequestMethod.OPTIONS) public ResponseEntity<?> handleOptionsRequest( @RequestHeader("Access-Control-Request-Method") String requestMethod, @RequestHeader("Access-Control-Request-Headers") String requestHeaders) { HttpHeaders headers = new HttpHeaders(); headers.set("Access-Control-Allow-Origin", "*"); headers.set("Access-Control-Allow-Methods", requestMethod); headers.set("Access-Control-Allow-Headers", requestHeaders); return ResponseEntity.ok().headers(headers).build(); } @RequestMapping(value = "/cors", method = RequestMethod.PUT) public ResponseEntity<?> handlePutRequest(@RequestHeader("X-Custom-Request") String customRequest) { System.out.println(customRequest); // Beomy HttpHeaders headers = new HttpHeaders(); headers.set("Access-Control-Allow-Origin", "*"); return ResponseEntity.ok().headers(headers).build(); } }
- ๋ธ๋ผ์ฐ์ ์ ์๋ฐ์คํฌ๋ฆฝํธ์์ย
X-Custom-Request
ย ํค๋์ยBeomy
ย ๊ฐ์ ์๋ฒ์ ์ ๋ฌํ์๊ณ , ์๋ฒ์์๋ยAccess-Control-Allow-Headers
ย ํค๋์ยAccess-Control-Request-Headers
ย ํค๋ ๊ฐ์ ์ ์ฅํ์ฌ ์๋ฒ์์ยX-Custom-Request
ย ๊ฐ์ ์ฌ์ฉํ ์ ์๊ฒ ํ ์ฝ๋
- ๋ธ๋ผ์ฐ์ ์ ์๋ฐ์คํฌ๋ฆฝํธ์์ย
-
-
Access-Control-Max-Age:
- ์ธ์ ๊น์ง ์ด์๋จ์ ์ ์๋์ง -
์ฌ์ฉ๋ฐฉ๋ฒ : ์๋์ ๊ฐ์ด ์ด ๋จ์๋ก ์บ์ ์๊ฐ์ ์ค์
Access-Control-Max-Age: 60
- ์์ ์ฝ๋๋ 60์ด ๋์ preflight ์์ฒญ์ ์บ์ ํ๋ ์ฝ๋.
- 60์ด ๋์ย
OPTIONS
ย ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ์๋น ์์ฒญ์ ๋ณด๋ด์ง ์์
-
์์
1 2 3 4 5
fetch('http://localhost:3001/cors', { method: 'PUT' }).then(function(response) { }).catch(function(error) { })
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
@RestController public class CorsController { @RequestMapping(value = "/cors", method = RequestMethod.OPTIONS) public ResponseEntity<?> handleOptionsRequest( @RequestHeader("Access-Control-Request-Method") String requestMethod) { HttpHeaders headers = new HttpHeaders(); headers.set("Access-Control-Allow-Origin", "*"); headers.set("Access-Control-Allow-Methods", requestMethod); headers.set("Access-Control-Max-Age", "60"); return ResponseEntity.ok().headers(headers).build(); } @RequestMapping(value = "/cors", method = RequestMethod.PUT) public ResponseEntity<?> handlePutRequest() { HttpHeaders headers = new HttpHeaders(); headers.set("Access-Control-Allow-Origin", "*"); return ResponseEntity.ok().headers(headers).build(); } }
-
-
Access-Control-Allow-Credentials: true
-
์ธ์ฆ์ ๋ณด๋ฅผ ๋ด์์ ๋ณด๋ผ ์ ์๋์ง ์ค๋ฅ๊ฐ๋๋ฉด true๋ก ๋ณด๋ด๋ฉด ํด๊ฒฐํ ์ ์์. (Credential: ์๊ฒฉ์ฆ๋ช )
-
๋ธ๋ผ์ฐ์ ์์ ์ฟ ํค๊ฐ์ ๊ฑธ ์ฌ์ฉํ๋๋ฐ ํ์ฉํ๋์ง๋ฅผ ๋ด๋ ๊ฒ.
- ๊ฐ๋ฐ์๋๊ตฌ์์ ์ฟ ํคํ์ธ ๊ฐ๋ฅ. ์ฟ ํค๋ ๋ธ๋ผ์ฐ์ ๊ฐ ๊ด๋ฆฌ
-
์ฌ์ฉ๋ฐฉ๋ฒ
Access-Control-Allow-Credentials: true
-
์์
1 2 3 4 5 6
fetch('http://localhost:3001/cors', { method: 'PUT', credentials: 'include' }).then(function(response) { }).catch(function(error) { })
-
์๋์ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์
-
์๋ฒ์์ ์๋์ ๊ฐ์ด ์๋ต ํค๋๋ฅผ ์ถ๊ฐํด ์ฃผ์ด์ผ ํจ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
@RestController public class CorsController { @RequestMapping(value = "/cors", method = RequestMethod.OPTIONS) public ResponseEntity<?> handleOptionsRequest( @RequestHeader("Access-Control-Request-Method") String requestMethod) { HttpHeaders headers = new HttpHeaders(); headers.set("Access-Control-Allow-Origin", "https://www.google.com"); headers.set("Access-Control-Allow-Methods", requestMethod); headers.set("Access-Control-Allow-Credentials", "true"); return ResponseEntity.ok().headers(headers).build(); } @RequestMapping(value = "/cors", method = RequestMethod.PUT) public ResponseEntity<?> handlePutRequest() { HttpHeaders headers = new HttpHeaders(); headers.set("Access-Control-Allow-Origin", "https://www.google.com"); headers.set("Access-Control-Allow-Credentials", "true"); return ResponseEntity.ok().headers(headers).build(); } }
-
Access-Control-Allow-Credentials: true
ย ์ถ๊ฐ ๋ฟ๋ง ์๋๋ผ,ยAccess-Control-Allow-Origin
ย ํค๋๋ย*
(์์ผ๋์นด๋)๊ฐ ์๋ ์ถ์ฒ๋ฅผ ๋ช ์ํด ์ฃผ์ด์ผ ํฉ๋๋ค.
-
-
HTTP (HyperText Transfer Protocol)
-
HTML๊ณผ ๊ฐ์ ๋ฌธ์๋ฅผ ์ ์กํ๊ธฐ ์ํ Application Layer ํ๋กํ ์ฝ
-
HTTP๋ ์น ๋ธ๋ผ์ฐ์ ์ ์น ์๋ฒ์ ์ํต์ ์ํด ๋์์ธ ๋จ.
-
์ ํต์ ์ธ ํด๋ผ์ด์ธํธ-์๋ฒ ๋ชจ๋ธ์์ ํด๋ผ์ด์ธํธ๊ฐ HTTP messages ์์์ ๋ง์ถฐ ์์ฒญ์ ๋ณด๋ด๋ฉด, ์๋ฒ๋ HTTP messages ์์์ ๋ง์ถฐ ์๋ตํจ
-
HTTP๋ ํน์ ์ํ๋ฅผ ์ ์งํ์ง ์๋ ํน์ง์ด ์์ , Stateless(๋ฌด์ํ์ฑ)
HTTP Message
-
ํด๋ผ์ด์ธํธ์ ์๋ฒ ์ฌ์ด์์ ๋ฐ์ดํฐ๊ฐ ๊ตํ๋๋ ๋ฐฉ์
-
๋๊ฐ์ง ์ ํ
- ์์ฒญ(Requests)
- ์๋ต(Responses)
-
๊ตฌ์กฐ
- ๋ช ์ค์ ํ ์คํธ ์ ๋ณด๋ก ๊ตฌ์ฑ
- ์ง์ ์์ฑ ํ์ ์์ โ ๊ตฌ์ฑํ์ผ, API, ๊ธฐํ ์ธํฐํ์ด์ค์์ ์๋์ผ๋ก ์์ฑํจ
- ์์ฒญ๊ณผ ์๋ต์ ๋ค์๊ณผ ๊ฐ์ ์ ์ฌํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง
- start line
- ์์ฒญ์ด๋ ์๋ต์ ์ํ๋ฅผ ๋ํ๋
- ํญ์ ์ฒซ ๋ฒ์งธ ์ค์ ์์น
- ์๋ต์์๋ status line์ด๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
- empty line - ํค๋์ ๋ณธ๋ฌธ์ ๊ตฌ๋ถํ๋ ์ญํ .
- body
- ์์ฒญ๊ณผ ๊ด๋ จ๋ ๋ฐ์ดํฐ๋ ์๋ต๊ณผ ๊ด๋ จ๋ ๋ฐ์ดํฐ ๋๋ ๋ฌธ์๋ฅผ ํฌํจ
- ์์ฒญ๊ณผ ์๋ต์ ์ ํ์ ๋ฐ๋ผ ์ ํ์ ์ผ๋ก ์ฌ์ฉ
- ์ด ์ค start line๊ณผ HTTP headers๋ฅผ ๋ฌถ์ด ์์ฒญ์ด๋ ์๋ต์ ํค๋(head)๋ผ๊ณ ํ๊ณ , payload๋ body๋ผ๊ณ ์ด์ผ๊ธฐ ํจ
- start line
์์ฒญ
HTTP ์์ฒญ์ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ๋ณด๋ด๋ ๋ฉ์์ง
1. start line
- 3๊ฐ์ง ์์๊ฐ ์์
- Mehtod = HTTP METHOD โ ์ํํ ์์
์ด๋ ๋ฐฉ์์ ์ค๋ช
- GET, POST, DELETE, PUT = CRUD
- HEAD or OPTIONS
- ์์ = ์์ฒญํ๋ ์ฃผ์
- ์ผ๋ฐ์ ์ผ๋ก (URL์ด๋ URI) ๋๋ ํ๋กํ ์ฝ, ํฌํธ, ๋๋ฉ์ธ์ ์ ๋ ๊ฒฝ๋ก
- ์์
- origin ํ์
?
์ ์ฟผ๋ฆฌ ๋ฌธ์์ด์ด ๋ถ๋ ์ ๋ ๊ฒฝ๋ก- POST, GET, HEAD, OPTIONS ๋ฑ์ method์ ํจ๊ป ์ฌ์ฉ
POST / HTTP 1.1 GET /background.png HTTP/1.0 HEAD /test.html?query=alibaba HTTP/1.1 OPTIONS /anypage.html HTTP/1.0
- absolute ํ์
- ์์ ํ URL ํ์์ผ๋ก, ํ๋ก์์ ์ฐ๊ฒฐํ๋ ๊ฒฝ์ฐ ๋๋ถ๋ถ GET method์ ํจ๊ป ์ฌ์ฉ
GET <http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages> HTTP/1.1
- authority ํ์
- ๋๋ฉ์ธ ์ด๋ฆ๊ณผ ํฌํธ ๋ฒํธ๋ก ์ด๋ฃจ์ด์ง URL์ authority component
- HTTP ํฐ๋์ ๊ตฌ์ถํ๋ ๊ฒฝ์ฐ,
CONNECT
์ ํจ๊ป ์ฌ์ฉ๊ฐ๋ฅCONNECT developer.mozilla.org:80 HTTP/1.1
- origin ํ์
- start line์ HTTP ๋ฒ์ ์ ํจ๊ป ์
๋ ฅ
- HTTP ๋ฒ์ ์ ๋ฐ๋ผ HTTP message์ ๊ตฌ์กฐ๊ฐ ๋ฌ๋ผ์ง
- Mehtod = HTTP METHOD โ ์ํํ ์์
์ด๋ ๋ฐฉ์์ ์ค๋ช
2. Header
-
๊ธฐ๋ณธ๊ตฌ์กฐ์ ๋ฐ๋ฆ
-
ํค๋ ์ด๋ฆ(๋์๋ฌธ์ ๊ตฌ๋ถ์ด ์๋ ๋ฌธ์์ด), ์ฝ๋ก ( : ), ๊ฐ์ ์ ๋ ฅ
-
๊ฐ์ ํค๋์ ๋ฐ๋ผ ๋ค๋ฆ โ ์ฌ๋ฌ ์ข ๋ฅ์ ํค๋๊ฐ ์๊ณ , ๋ค์๊ณผ ๊ฐ์ด ๊ทธ๋ฃน์ ๋๋ ์ ์์
- General headers
- ๋ฉ์์ง ์ ์ฒด์ ์ ์ฉ๋๋ ํค๋, body๋ฅผ ํตํด ์ ์ก๋๋ ๋ฐ์ดํฐ์๋ ๊ด๋ จ์ด ์๋ ํค๋
- Request headers
- fetch๋ฅผ ํตํด ๊ฐ์ ธ์ฌ ๋ฆฌ์์ค๋ ํด๋ผ์ด์ธํธ ์์ฒด์ ๋ํ ์์ธํ ์ ๋ณด๋ฅผ ํฌํจํ๋ ํค๋๋ฅผ ์๋ฏธ
- User-Agent, Accept-Type, Accept-Language๊ณผ ๊ฐ์ ํค๋๋ ์์ฒญ์ ๋ณด๋ค ๊ตฌ์ฒดํ ํจ.
- Referer์ฒ๋ผ ์ปจํ ์คํธ๋ฅผ ์ ๊ณตํ๊ฑฐ๋ If-None๊ณผ ๊ฐ์ด ์กฐ๊ฑด์ ๋ฐ๋ผ ์ ์ฝ์ ์ถ๊ฐ๊ฐ๋ฅ
- Representation headers (=์ด์ ์ Entity headers๋ผ ๋ถ๋ฆผ)
- body์ ๋ด๊ธด ๋ฆฌ์์ค์ ์ ๋ณด(์ฝํ ์ธ ๊ธธ์ด, MIME ํ์ ๋ฑ)๋ฅผ ํฌํจํ๋ ํค๋
3. Body
- HTTP messages ๊ตฌ์กฐ์ ๋ง์ง๋ง์ ์์น,
- ๋ชจ๋ ์์ฒญ์ body๊ฐ ํ์ํ์ง ์์.(GET, HEAD, DELETE, OPTIONS์ฒ๋ผ ์๋ฒ์ ๋ฆฌ์์ค๋ฅผ ์์ฒญํ๋ ๊ฒฝ์ฐ๋ ํ์์์) โ Request์ผ ๋ get ์์ฒญ์ ๋ฐ๋์ ์ด๋ค ์ ๋ณด๋ฅผ ๋ด์ ์ ์์ (get์ ์กฐํ์ด๊ธฐ ๋๋ฌธ์)
- POST๋ PUT๊ณผ ๊ฐ์ ์ผ๋ถ ์์ฒญ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธํ๊ธฐ ์ํด ์ฌ์ฉ
- ๋ณดํธ์ ์ผ๋ก JSON ์ผ๋ก ๋ณด๋
- ๋ ์ข
๋ฅ๋ก ๋๋ ์ ์์
- Single-resource bodies(๋จ์ผ-๋ฆฌ์์ค ๋ณธ๋ฌธ):
- ํค๋ ๋ ๊ฐ(Content-Type๊ณผ Content-Length)๋ก ์ ์๋ ๋จ์ผ ํ์ผ๋ก ๊ตฌ์ฑ
- Multiple-resource bodies(๋ค์ค-๋ฆฌ์์ค ๋ณธ๋ฌธ) :
- ์ฌ๋ฌ ํํธ๋ก ๊ตฌ์ฑ๋ ๋ณธ๋ฌธ์์๋ ๊ฐ ํํธ๋ง๋ค ๋ค๋ฅธ ์ ๋ณด๋ฅผ ์ง๋
- ๋ณดํต HTML form๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค. - form์ ์ด์ ์์.
- Single-resource bodies(๋จ์ผ-๋ฆฌ์์ค ๋ณธ๋ฌธ):
์๋ต
1. Status line
์๋ต์ ์ฒซ ์ค์ Status line์ด๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ, ๋ค์์ ์ ๋ณด๋ฅผ ํฌํจ
- ํ์ฌ ํ๋กํ ์ฝ์ ๋ฒ์ (HTTP/1.1)
- ์ํ ์ฝ๋ - ์์ฒญ์ ๊ฒฐ๊ณผ๋ฅผ ๋ํ๋ ๋๋ค. (200, 302, 404 ๋ฑ)
- ์ํ ํ ์คํธ - ์ํ ์ฝ๋์ ๋ํ ์ค๋ช
Status line์ HTTP/1.1 404 Not Found.
์ฒ๋ผ ์๊ฒผ์ต๋๋ค.
2. Headers
์๋ต์ ๋ค์ด๊ฐ๋ HTTP headers๋ ์์ฒญ ํค๋์ ๋์ผํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง
๊ทธ๋ฃน์ผ๋ก ๋๋ ์ ์์
โ
- General headers
- ๋ฉ์์ง ์ ์ฒด์ ์ ์ฉ๋๋ ํค๋๋ก, body๋ฅผ ํตํด ์ ์ก๋๋ ๋ฐ์ดํฐ์๋ ๊ด๋ จ์ด ์๋ ํค๋
- Response headers
- ์์น ๋๋ ์๋ฒ ์์ฒด์ ๋ํ ์ ๋ณด(์ด๋ฆ, ๋ฒ์ ๋ฑ)์ ๊ฐ์ด ์๋ต์ ๋ํ ๋ถ๊ฐ์ ์ธ ์ ๋ณด๋ฅผ ๊ฐ๋ ํค๋๋ก, Vary, Accept-Ranges์ ๊ฐ์ด ์ํ ์ค์ ๋ฃ๊ธฐ์๋ ๊ณต๊ฐ์ด ๋ถ์กฑํ๋ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ ๊ณต
- Representation headers
- body์ ๋ด๊ธด ๋ฆฌ์์ค์ ์ ๋ณด(์ฝํ ์ธ ๊ธธ์ด, MIME ํ์ ๋ฑ)๋ฅผ ํฌํจํ๋ ํค๋
3. Body
201, 204์ ๊ฐ์ ์ํ ์ฝ๋๋ฅผ ๊ฐ์ง๋ ์๋ต์๋ ๋ณธ๋ฌธ์ด ํ์์์.
์๋ต์ body๋ ๋ ์ข ๋ฅ
- Single-resource bodies(๋จ์ผ-๋ฆฌ์์ค ๋ณธ๋ฌธ)
- ๊ธธ์ด๊ฐ ์๋ ค์ง ๋จ์ผ-๋ฆฌ์์ค ๋ณธ๋ฌธ์ ๋ ๊ฐ์ ํค๋(Content-Type, Content-Length)๋ก ์ ์
- ๊ธธ์ด๋ฅผ ๋ชจ๋ฅด๋ ๋จ์ผ ํ์ผ๋ก ๊ตฌ์ฑ๋ ๋จ์ผ-๋ฆฌ์์ค ๋ณธ๋ฌธ์ Transfer-Encoding์ด
chunked
๋ก ์ค์ ๋์ด ์์ผ๋ฉฐ, ํ์ผ์ chunk๋ก ๋๋์ด ์ธ์ฝ๋ฉ๋์ด ์์
- Multiple-resource bodies(๋ค์ค-๋ฆฌ์์ค ๋ณธ๋ฌธ)
- ์๋ก ๋ค๋ฅธ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ body
HTTP ์ํ ์ฝ๋ - ์ธ์ฐ๊ธฐ
์ค๋ฅ๋ฉ์ธ์ง๋ ์คํ๋ง์์ ENUM Class ๋ง๋ค์ด์ ์ฌ์ฉ [๋ ๋ง์ HTTP ์ํ์ฝ๋๋ ๋งํฌ์ฐธ์กฐ๐ฉ] (https://developer.mozilla.org/ko/docs/Web/HTTP/Status)
โ๏ธโจํ๊ธฐ ํ๋ ๊ผญ ์ธ์์ผํ๋ ์ํ์ฝ๋!
HTTP ์ํ์ฝ๋ | ย | ย | name | description |
---|---|---|---|---|
100๋ฒ๋ | ์ด๋ค ์ ๋ณด๋ฅผ ํ์ํ ๋ ์ฌ์ฉ | ย | ย | ย |
200๋ฒ๋ | ์ฑ๊ณตํ์๋ ์ฌ์ฉํ๋ ์ฝ๋ | 200 | OK | ์์ฒญ์ด ์ฑ๊ณต์ ์ผ๋ก ์ํ๋์์ต๋๋ค. |
ย | ย | 201 | Created | ๋ฆฌ์์ค๋ฅผ ์์ฑํ๋ ์์ฒญ์ด ์ฑ๊ณต์ ์ผ๋ก ์ํ๋์์ต๋๋ค. |
ย | ย | 202 | Accepted | ์์ฒญ์ด ์ ์๋์๋๋ฐ, ์์ ํ ์ฒ๋ฆฌ๋์ง ์์์ต๋๋ค. |
ย | ย | 204 | No Content | ์์ฒญ์ด ์ฑ๊ณต์ ์ผ๋ก ์ํ๋์์ผ๋, ์๋ตํ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค. |
300๋ฒ๋ | Redirection | 301 | Moved Permanently | ๋ฆฌ์์ค์ ์์น๊ฐ ๋ณ๊ฒฝ๋์์์ ์๋ ค์ค๋๋ค. ์๋ก์ด ๋ฆฌ์์ค์ ์์น๋ฅผ ํจ๊ป ๋ฐํํฉ๋๋ค. |
ย | ย | 302 | Found | ๋ฆฌ์์ค์ ์์น๊ฐ ์์๋ก ๋ณ๊ฒฝ๋์ด์, ์์ ์ฃผ์๋ก ์์ฒญ์ ๋ณด๋ ๋๋ค. |
400๋ฒ๋ | ํด๋ผ์ด์ธํธ ์ค๋ฅ | 400 | Bad Request | ์์ฒญ์ด ์๋ชป๋์์ต๋๋ค. |
ย | ย | 401 | Unauthorized | ์ธ์ฆ์ด ํ์ํฉ๋๋ค. ํด๋ผ์ด์ธํธ์์ ์ธ์ฆ ์ ๋ณด๋ฅผ ํฌํจํด์ ๋ณด๋ด์ผ ํฉ๋๋ค. |
ย | ย | 403 | Forbidden | ๊ถํ์ด ์์ต๋๋ค. |
ย | ย | 404 | Not Found | ์์ฒญํ ๋ฆฌ์์ค๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. |
ย | ย | 405 | Method Not Allowed | ์ด ๋ฉ์๋๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. |
500๋ฒ๋ | ์๋ฒ์ค๋ฅ | 500 | Server Error | ์๋ฒ์์ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. |
ย | ย | 501 | Not Implemented | ํด๋น ๊ธฐ๋ฅ์ ์ง์ํ์ง ์์ต๋๋ค. |
ย | ย | 502 | Bad Gateway | ์๋ฒ๊ฐ ๊ฒ์ดํธ์จ์ด ํน์ ํ๋ก์๋ก๋ถํฐ ์๋ชป๋ ์๋ต์ ๋ฐ์์ต๋๋ค. |
ย | ย | 503 | Service Unavailable | ์๋ฒ๊ฐ ํ์ฌ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. (์๋ฒ๊ฐ ๊ณผ๋ถํ์ผ ๊ฒฝ์ฐ) |
ย | ย | 504 | Gateway Timeout | ์๋ฒ๊ฐ ๊ฒ์ดํธ์จ์ด ํน์ ํ๋ก์๋ก๋ถํฐ ๋๊ธฐ ์๊ฐ๋์ ์๋ต์ ๋ฐ์ง ๋ชปํ์ต๋๋ค. |
REST API
- ๋ฐ์ดํฐ๋ ์์(Resource)์ HTTP URI๋ก ํํํ๊ณ , HTTP ํ๋กํ ์ฝ์ ํตํด ์์ฒญ๊ณผ ์๋ต์ ์ ์ํ๋ ๋ฐฉ์
- REST API์์ REST๋ โRepresentational State Transferโ์ ์ฝ์
- API ์ ์งํค๋ฉด ์ํด๋ณธ ํฐ๊ฐ ๋จ - ๋๊ตฌ๋ ๊ฐ๋ฐ์๋ผ๋ฉด ์์์ผํ๋ ๊ฒ.
Method
-
GET : ์กฐํํ ๋ ์ฌ์ฉ
- ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ๋ณํ์ํค์ง ์๋ ์์ฒญ์ ์ฌ์ฉ
- 1๋ฒ ํ์์ ์ ๋ณด๋ฅผ ์ฃผ์ธ์ ํ๋ฉด ์๋ต์ด ๋ฌ๋ผ์ง๋ฉด ์๋จ.
- body์ ๋ฐ์ดํฐ ๋ด์ ์ ์์. โ query parameter๋ฅผ ์ฌ์ฉํ์ฌ ํ์ํ ๋ฆฌ์์ค๋ฅผ ์ ๋ฌ
-
POST : ์์ฑ ๋ฐ ์ฒ๋ฆฌ
-
get ๋ณด๋ค๋ ๊ด๋ฒ์ํ๊ฒ ์ฌ์ฉ
-
์์ฑํ ๋ ์ฌ์ฉ, body์ ๋ฐ์ดํฐ ๋ด์ ์ ์์.
์ค๊ดํธ๊ฐ body๋ฅผ ๋ปํ๊ณ , json type
-
์์ฒญ๋ง๋ค ์๋ก์ด ๋ฆฌ์์ค๋ฅผ ์์ฑ
-
-
PUT, PATCH
- PATCH : ๋ฐ์ดํฐ๋ฅผ ์ผ๋ถ๋ถ๋ง ์์ ํ ๋
- PUT : ์ ๋ณด๋ฅผ ์ ์ฒด ๋ณ๊ฒฝ ์ , ๋ณ๊ฒฝํ๊ณ ์ ํ๋ ๋ฐ์ดํฐ๊ฐ ์์ ๊ฒฝ์ฐ ์์ฑ๋ ํจ.
- PUT์ ์์ฒญ๋ง๋ค ๊ฐ์ ๋ฆฌ์์ค๋ฅผ ๋ฐํ = ๋ฉฑ๋ฑ์ฑ.
- body์ data๋ฅผ ๋ด์ ์ ์์.
-
DELETE
- ํผ๋ ๊ธ, ๋ฐ์ดํฐ, ํ์ ๋ฑ ์ญ์ ํ ๋
-
HEAD
- Resource์ Head ์ ๋ณด ์์ฒญํ ๋
- ์ง๊ธ์ ์ฌ์ฉํ ์ผ ์์ฃผ ์์
ํ๋ก์ ํธ์ API ์ค๊ณํ ๋ ์์ฝ๋๋ฉด body์ ๊ตณ์ด ์์ฝ๋์๋ค๊ณ ๋ฌธ๊ตฌ ๋ณด๋ด๋๋ฐ ํ์ ์์.
200์ด๋ผ๋ ์ฝ๋๋ง ๋ณด๋ด๋ฉด ์์ฝ์ด ๋ ๊ฒ์ ์ด๊ฒ์ผ๋ก ํ์ธํ ์ ์๊ธฐ ๋๋ฌธ์
REST API๋ฅผ ์ ์ ์ฉํ๊ธฐ ์ํ 4๋จ๊ณ
๋ฆฌ์ฒ๋์จ์ REST ์ฑ์๋ ๋ชจ๋ธ์ ๊ตฌ์กฐํ
3๋จ๊ณ ๊น์ง ์งํค๊ธฐ ์ด๋ ค์
1,2 ๋จ๊ณ ์ค์ - ์ธ์์ผํจ!
0 ๋จ๊ณ
-
๋จ์ํ HTTP ํ๋กํ ์ฝ์ ์ฌ์ฉํ๊ธฐ๋ง ํด๋ ๋จ
-
๋ฌผ๋ก ์ด ๊ฒฝ์ฐ, ํด๋น API๋ฅผ REST API๋ผ๊ณ ํ ์๋ ์์ผ๋ฉฐ, 0๋จ๊ณ๋ ์ข์ REST API๋ฅผ ์์ฑํ๊ธฐ ์ํ ๊ธฐ๋ณธ ๋จ๊ณ
-
ํ์ค์ด๋ผ๋ ์ด๋ฆ์ ์ฃผ์น์์ ์์ฝ ๊ฐ๋ฅํ ์๊ฐ์ ํ์ธํ๊ณ , ์ด๋ค ํน์ ์๊ฐ์ ์์ฝํ๋ ์ํฉ์ ์๋ก ๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
- ์ ํ์์ ์๋ชป ๋ ๊ฒ
- ์กฐํ์ธ๋ฐ POST ์ฌ์ฉ์ ๋ถ๊ฐ๋ฅ ํ ๊ฒ, ๊ทธ๋ฆฌ๊ณ body์ ๋ฐ์ดํฐ ๋ฃ์ ๊ฒ์ ์๋ชป ๋ ๊ฒ์.
- ์๊ฐ์ ํฌ์ธํธ๋ฅผ ์ก์ง์๊ณ ํ์ค์ด๋ผ๋ ์์์ ํฌ์ธํธ๋ฅผ ์ก์์ผ ํจ.
- slot์ ์๋ต์ด ์๊ธฐ ๋๋ฌธ์ slot์ ๋ค์ด๊ฐ์ผ ํจ. ๊ทธ๋ฆฌ๊ณ slot์ ์๋ณ์๊ฐ ํ์
- ์ ํ์์ ์๋ชป ๋ ๊ฒ
1๋จ๊ณ
-
1๋จ๊ณ์์๋ ๊ฐ๋ณ ๋ฆฌ์์ค์์ ํต์ ์ ์ค์ํด์ผ ํจ
-
๋ชจ๋ ๋ฐ์ดํฐ๋ ์์(Resource)์ HTTP URI๋ก ํํ
-
๋ชจ๋ ์์์ ๊ฐ๋ณ ๋ฆฌ์์ค์ ๋ง๋ ์๋ํฌ์ธํธ(Endpoint)๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๋ ๊ฒ๊ณผ ์์ฒญํ๊ณ ๋ฐ์ ์์์ ๋ํ ์ ๋ณด๋ฅผ ์๋ต์ผ๋ก ์ ๋ฌ
- doctors๋ก ๋ณ๊ฒฝ๋์๊ณ
- slot์ ๋ฐฐ์ด๋ก ๋ด๊ฒจ์์. jsonํํ๋ผ์
- id : 123์ผ๋ก ๋ณ๊ฒฝ ๋จ
-
์์ฝ์ ์คํจํ๋ค๋ ์ด์ ๊ฐ ์ฌ๋ฌ๊ฐ์ง์ผ ๊ฒฝ์ฐ์๋ response๋ฅผ ๋ฃ์ด ์ค ์ ์์ (์ด์ ๊ฐ ์ถฉ๋ถํ ๋)
-
์คํจํ ๊ฒฝ์ฐ ๋ค์ ํธ์ถ
-
๋ค์ ํธ์ถํ ๋๋ ๋ถ๊ฐ๋ฅ ํ ๋ฐ์ดํฐ๋ ๋ณด์ด์ง ์์์ผ ํจ.
2๋จ๊ณ
-
2๋จ๊ณ์์๋ CRUD์ ๋ง๊ฒ ์ ์ ํ HTTP ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ค์
-
POSTโ GET
- ํน์ ์๊ฐ์ ์์ฝํ๋ค๋ ๊ฒ์ GET ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์ฒญ์ ๋ณด๋ด๊ณ , ์ด๋ GET ๋ฉ์๋๋ body๋ฅผ ๊ฐ์ง์ง ์๊ธฐ ๋๋ฌธ์ query parameter๋ฅผ ์ฌ์ฉํ์ฌ ํ์ํ ๋ฆฌ์์ค๋ฅผ ์ ๋ฌ
-
POST์ PUT์ ๊ตฌ๋ถํด์ ์ฌ์ฉ
- POST๋ ์์ฒญ๋ง๋ค ์๋ก์ด ๋ฆฌ์์ค๋ฅผ ์์ฑ
- PUT์ ์์ฒญ๋ง๋ค ๊ฐ์ ๋ฆฌ์์ค๋ฅผ ๋ฐํ = ๋ฉฑ๋ฑ์ฑ.
-
PUT๊ณผ PATCH ๋ ๊ตฌ๋ถํ์ฌ ์ฌ์ฉ
- PUT์ ๊ต์ฒด, PATCH๋ ์์ ์ ์ฉ๋๋ก ์ฌ์ฉ
-
201 Created๋ก ๋ช ํํ๊ฒ ์์ฑํด์ผ ํ๋ฉฐ, ๊ด๋ จ ๋ฆฌ์์ค๋ฅผ ํด๋ผ์ด์ธํธ๊ฐ Location ํค๋์ ์์ฑ๋ URI๋ฅผ ํตํด ํ์ธํ ์ ์๋๋ก. ๊ทผ๋ฐ ์ค์ ๋ก ์ฌ์ฉ ์ ์ํจ
-
๋ฐ์ดํฐ ์กฐํํ๊ณ (GET) ์ฌ์กฐํ ํ ๊ฒฝ์ฐ ๋ฉฑ๋ฑ์ฑ์ ํค์น๋ ๊ฒฝ์ฐ๊ฐ ์๊น
3๋จ๊ณ
-
HATEOAS(Hypertext As The Engine Of Application State)๋ผ๋ย ์ฝ์ด๋ก ํํ๋๋ ํ์ดํผ๋ฏธ๋์ด ์ปจํธ๋กค์ ์ ์ฉ
-
์๋ต์๋ ๋ฆฌ์์ค์ URI๋ฅผ ํฌํจํ ๋งํฌ ์์๋ฅผ ์ฝ์ ํ์ฌ ์์ฑํ๋ค
-
์๋ตย ๋ด์ย ์๋ก์ดย ๋งํฌ๋ฅผย ๋ฃ์ดย ์๋ก์ดย ๊ธฐ๋ฅ์ ์ ๊ทผํ ์ ์๋๋ก ํ๋ ๊ฒ์ด 3๋จ๊ณ์ ์ค์ ํฌ์ธํธ
-
์์ ์ด ์๋ ์ ๋ฉํ ๊ฒ์ POST ์ฌ์ฉํ๊ธฐ. +์ฝ๋ ์์จ์ผ ํจ
Open API์ API Key
- Open API
- ์ ๋ถ์์ ์ ๊ณตํ๋ ๊ณต๊ณต๋ฐ์ดํฐ : ๊ณต๊ณต๋ฐ์ดํฐ ํฌํธ
- Open Weather Map : ์น ์ฌ์ดํธ์์ ์ ๊ณตํ๋ ๋ ์จ API
- ๋ฐ์ดํฐ๋ฅผ JSON ํํ๋ก ์๋ต
- API Key
- API key๋ ์๋ฒ์ ๋ฌธ์ ์ฌ๋ ์ด์
- ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋ฐ๋ผ ์๋ฒ์์ ์๋ตํ๋ค๋ ๋ง์ ๊ฒฐ๊ตญ ์๋ฒ๋ฅผ ์ด์ฉํ๋ ๋ฐ์ ๋น์ฉ์ด ๋ฐ์
- ๊ทธ๋์ ๋ก๊ทธ์ธ๋ ์ด์ฉ์์๊ฒ๋ง ์์์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ API Key์ ํํ๋ก ์ ๊ณตํ๊ณ , ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ ๋ API key๋ฅผ ๊ฐ์ด ์ ๋ฌํด์ผ๋ง ์ํ๋ ์๋ต์ ๋ฐ์ ์ ์์.
REST API ์ค์ต
API ์ค๊ณ
- ์ด๋ฆ์ ๋์ฌ ์ฌ์ฉ ์๋จ, endpoint์ ๊ธฐ๋ณธ์ ๋ณต์ํ์.
- ๋๋ฌธ์์ ๋์ฌ ์ฌ์ฉํ์ง ์์.
- ์ฌ์ฉ์๊ฐ ๊ธฐ๋ณธํค ์ ์ ์์ - ๊ธฐ๋ณธํค๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ค์ ํ๊ฒ ํจ.
- ๊ธฐ์กด ์๋น์ค์์ ์ด๋ป๊ฒ ์๋ณํ๋์ง ์์ฃผ ๋ณด๊ธฐ
โ๏ธ ์ค์ต
-
๋์ ์ถ๊ฐ (Create a Book)
POST/books
{โnameโ : โsleepโ,
โregisterdateโ : โ2024-05-31โ,
โauthorโ : โjerryโ} -
๋์ ๋ชฉ๋ก ์กฐํ (Get All Books)
GET/books
-
ํน์ ๋์ ์กฐํ (Get a Single Book)
GET/books/id
๊ธฐ๋ณธ ํค๋ก ์กฐํํ ์ ์์ผ๋ฏ๋ก id๊ฐ ์๋ ์ฐพ๊ณ ์ ํ๋ ์ด๋ฆ์ด๋ ์ ์ ๋ฑ์ผ๋ก ์กฐํํด์ผ ํจ.
-
๋์ ์ ๋ณด ์์ (Update a Book)
PATCH/books
-
๋์ ์ญ์ (Delete a Book)
Delete/books/id
-
๋์ ๋์ถ (Borrow a Book)
GET/books/name=sleepy?
POST/loanbooks/book/id
๋ด ์๊ฐ์๋ ์กฐํ๋ฅผ ํ๊ณ ๋์ถ ๋ชฉ๋ก์ ์์ฑํด์ผ ํ๋ค๊ณ ์๊ฐํ์
ํ์ง๋ง ๋ฐ๋ก ๋์ถ๋ชฉ๋ก์์ ์์ฑํ๋ ๊ฒ์ด ์ ์
POST โ /loanrecords
{
โbookIdโ: 3,
โuserIdโ: 11,
โloanDateโ โ2024-05-30โ -
๋์ ๋ฐ๋ฉ (Return a Book)
GET/loanbooks/id
POST/loanbooks/id
๋ง์ฐฌ๊ฐ์ง๋ก ์ฑ ๋ฐ์ฝ๋๋ก ์กฐํ ํ ๋์ถ ๋ชฉ๋ก์ด ์ผ๋ถ๋ถ ์์ ๋๋ค๊ณ ์๊ฐํจ.
๊ทธ๋ฌ๋ ๋์ถ๋ชฉ๋ก๋ง ์์ ํ๋ ๊ฒ์ด ์ ์
ex) PATCH โ /loanrecords/3
res ->
{
โloanIdโ: 3,
โuserIdโ: 2,
โbookIdโ: 7,~~~
} -
๋์ถ ๊ธฐ๋ก ์กฐํ (Get Loan Records)
Get/loanbooks/username=โjerryโ
userId โ GET /loanrecoreds?userId={id} โ ํน์ ์ ์ ์ ๋์ถ ๊ธฐ๋ก ์กฐํ
bookId โ GET /loanrecoreds?bookId ={id} โ ํน์ ๋์์ ๋์ถ ๊ธฐ๋ก ์กฐํ
loanDate โ GET /loanrecoreds?loanDate ={id} โ ํน์ ๋์ถ์ผ ๊ธฐ์ค ๋์ถ ๊ธฐ๋ก ์กฐํ
returnDate โ GET /loanrecoreds?returnDate ={id} โ ํน์ ๋ฐ๋ฉ์ผ ๊ธฐ์ค ๋์ถ ๊ธฐ๋ก ์กฐํ
isReturned โ GET /loanrecoreds?isReturned={id} โ ๋ฐ๋ฉ์ฌ๋ถ ๊ธฐ์ค ๋์ถ ๊ธฐ๋ก ์กฐํ
ex)
GET โ /loanrecords?userId=3?bookId=7 โ 3๋ฒ ์ ์ ๊ฐ 7๋ฒ ์ฑ ์ ๋น๋ฆฐ ๋์ถ ๊ธฐ๋ก ์กฐํ
Comment
- ๋ฐฐ์ด๋ด์ฉ : CORS, HTTP, REST API, REST API ์ค์ต
- CORS๋ ์ฒ์์ ์ด๋ ค์์ ์ดํดํ๋๋ฐ ์ค๋๊ฑธ๋ฆผ, ๋ ๋ ๋ ๋ง์ด ๋ด์ผํ ๊ฒ ๊ฐ์.
- ๐ Network ๋ถ๋ถ์ ๋จ์ํ ์ดํดํ๊ณ ๋์ด๊ฐ๊ธฐ์๋ ๋์ค์ ๋ง๋ฅ๋จ๋ ธ์ ๋ ์ด์ด์ด ์ด๊ฒ๋ญ์ผ ํ ๊ฒ ๊ฐ์ ๋ถ๋ถ์ด ์๋ค.
ํนํ CORS ๋ถ๋ถ, ์์ ๋ค์ ๋ ์~~ ํ๊ณ ๋ณ๊ฑฐ์๋๋ค ํ๋๋ฐ ๋ค์ ๋ณต์ตํ๋๋ฐ ์ ์ฒ์๋ณด๋ ๊ฒ ๊ฐ์ง ์ด๊ฑฐ..? ๋ฐฐ์ ์๋ ์ถ์๋ค.
์ฌ์ค simple๊ณผ Preflight์ ์ฐจ์ด์ ์ด๋ฐ์์ผ๋ก๋ง ์ดํดํ๊ณ ๊น๊ฒ๋ ์ดํดํ์ง ๋ชปํ๋ ๊ฒ์ด์๋ค.
์ง๊ธ ๊น๊ฒ๋ณด๊ธฐ ๋ณด๋ค ๋์ค์ ํ๋ก์ ํธํ ๋ ์ค๋ฅ๋๋ฉด ๊ทธ ๋ ๋ค์ ๋์์์ ๋ณด๋ผ๊ณ ํ์ จ๋๋ฐ
ํ์ ์ ์ด์ธ ๋๋ ๊ทธ๋ฐ ๋นํฉ์ค๋ฌ์ด ์ํฉ์ด ์๊ธฐ๊ธฐ ์ ์ ์ด์ ๋ณต์ต ๋ง์ด ํด์ผ๊ฒ ๋คโฆ!
Leave a comment