N๋นต

์œ„์น˜๊ธฐ๋ฐ˜ ๊ณต๋™๊ตฌ๋งค ํ”Œ๋žซํผ 'N๋นต'์ž…๋‹ˆ๋‹ค.<N๋นต>์€ ํ˜ผ์ž์‚ฌ๋Š” ๊ฒƒ๋ณด๋‹ค ๊ฐ™์ด ๊ตฌ๋งคํ•˜๋ฉด ๋” ์ด๋“์ด๋ผ๋ฉด?!
์ด์›ƒ๊ณผ ํ•จ๊ป˜ ๊ตฌ๋งคํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต๋™๊ตฌ๋งค ์ปค๋ฎค๋‹ˆํ‹ฐ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
์ž์‹ ์˜ ์ฃผ๋ณ€์—์žˆ๋Š” ๊ณต๊ตฌ ๊ฒŒ์‹œ๊ธ€์„ ์ž‘์„ฑํ•ด๋ณด๊ณ , ์ฐธ์—ฌํ•ด ๋ณด์„ธ์š”:)๋” ์ข‹์€ ์„œ๋น„์Šค๋กœ ๊ฐœ์„ ํ•ด๋‚˜๊ฐ€๊ธฐ์œ„ํ•ด ํ”ผ๋“œ๋ฐฑ ์ด๋ฒคํŠธ๋ฅผ ์ง„ํ–‰์ค‘์ž…๋‹ˆ๋‹ค.


๋งŽ์€ ๊ด€์‹ฌ๊ณผ ์ฐธ์—ฌ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

 

5์›” 25์ผ ~ 6์›” 1์ผ (23์‹œ 59๋ถ„)๊นŒ์ง€ ๊ณต๊ตฌ๊ฒŒ์‹œ๊ธ€์— ์ฐธ์—ฌํ•˜์‹œ๊ฑฐ๋‚˜,
ํ”ผ๋“œ๋ฐฑ์„ ์ž‘์„ฑํ•ด์ฃผ์‹  ๋ถ„๋“ค์—๊ฒŒ๋Š” ์ถ”์ฒจ์„ ํ†ตํ•ด ์น˜ํ‚จ3๋งˆ๋ฆฌ์™€ ๋ฉ”๊ฐ€์ปคํ”ผ ๊ธฐํ”„ํ‹ฐ์ฝ˜ 50์ž”์„ ๋นต๋นต ์ฉ๋‹ˆ๋‹ค!
๋‹น์ฒจ์ž ๋ฐœํ‘œ ๋ฐ ์ƒํ’ˆ ๋ฐœ์†ก์€ 2022๋…„ 6์›” 2์ผ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฐœ์†กํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค

 

N๋นต URL : https://nbbang.site

 

        Back-end(Node.js) : ์žฅ์œค์•„, ์˜ค๊ฒฝ์€, ํ•œ์žฌํ˜
        Front-end(React) : ๊ถŒ์˜๋ฏผ, ๊ณฝ์ง„ํ˜ธ, ์žฅ์ˆ˜์ฐฌ
        Designer(UI/UX) : ๊น€์›๊ฒฝ, ์ดํ™”์ •

 

์›น ํŽ˜์ด์ง€์™€ ๋ชจ๋ฐ”์ผ๋กœ๋„ ํ™•์ธ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค :)

 

 

 

5์ฃผ์ฐจ ํ•œ์ผ!

- ์†Œ์ผ“/ CRUD ๋ฒ„๊ทธ ์ˆ˜์ • ๋ฐ ์„œ๋น„์Šค๋ฐฐํฌ

- ํ…Œ์ŠคํŠธ ์„œ๋ฒ„ ์—ฐ๊ฒฐ

- ๋งˆ์ผ“ํŒ…, ์œ ์ €ํ”ผ๋“œ๋ฐฑ ๋ฐ˜์˜

 

์œ ์ €ํ”ผ๋“œ๋ฐฑ ๋ฐ ์ˆ˜์ •์‚ฌํ•ญ

1. ์ธํ„ฐ๋„ท์ด ๋Š๋ฆด ๊ฒฝ์šฐ ๊ธ€ ๋“ฑ๋กํ•˜๊ธฐ๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ ๋ˆ„๋ฅผ ์ˆ˜ ์žˆ๋Š” ํ˜„์ƒ์ด ์žˆ์Œ

(๊ฒŒ์‹œ๊ธ€์ด ์ค‘๋ณตํ•˜์—ฌ ์ƒ๊น€)

2. ๊ฐ€๊ฒฉ, ์ธ์›, ์ œ๋ชฉ, ์ƒ์„ธ์œ„์น˜, ๋‚ด์šฉ, ์ฑ„ํŒ… ๊ธ€์ž ์ˆ˜ ์ œํ•œ

3. ์„ค๋ช…ํŽ˜์ด์ง€์˜ ์ž˜๋ชป๋œ ์ด๋ฏธ์ง€ ๋ณ€๊ฒฝ

4. ๋น„๋กœ๊ทธ์ธ ์ƒํƒœ๋กœ ๋ฉ”์ธํŽ˜์ด์ง€ ์ ‘๊ทผ ์‹œ ๋ฐ”๋กœ ์„ค๋ช… ํŽ˜์ด์ง€ ๋ณด์—ฌ์ฃผ๊ธฐ

(์„ค๋ช…ํŽ˜์ด์ง€๊ฐ€ ๋ฏธํกํ•˜๋‹ค๋Š” ์˜๊ฒฌ์ด ์žˆ์–ด ์ถ”๊ฐ€ํ•  ์˜ˆ์ •)

5. ๊ฒŒ์‹œ๋ฌผ ์นดํ…Œ๊ณ ๋ฆฌ ์ถ”๊ฐ€

6. ์˜ค๋ฅธ์ชฝ ํ•˜๋‹จ์˜ ์‹œ/๊ตฌ/๋™ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๊ฒฝ์šฐ ํ•ด๋‹น ๋ ˆ๋ฒจ์— ๋งž๊ฒŒ ํ™”๋ฉด ๋ฒ”์œ„ ์„ค์ •

7. ์ฑ„ํŒ… ์œ ์ €๋ฆฌ์‹œํŠธ์—์„œ ์™ธ๋ถ€๋ฅผ ํด๋ฆญํ–ˆ์„ ๊ฒฝ์šฐ ๋‹ซํžˆ๊ฒŒ ์„ค์ •

8. ๋ธŒ๋ผ์šฐ์ € ํƒญ ์ƒ๋‹จ์˜ ๋ฐฐ๊ฒฝ์ด ํฐ์ƒ‰์ผ ๊ฒฝ์šฐ ๋กœ๊ณ ๊ฐ€ ๋ณด์ด์ง€ ์•Š์•„, ์ƒ‰์ƒ ์กฐ์ •

9. ๊ฒŒ์‹œ๊ธ€์ด ์—†์„ ๊ฒฝ์šฐ ์ƒ์„ฑ๋˜๋Š” ๋ฌธ๊ตฌ์˜ ๊ฐ„๊ฒฉ ์กฐ์ •

0. ์ฑ„ํŒ…์ฐฝ์—์„œ ์ด์šฉ์ž๊ฐ€ ์ด์ „ ๋‚ด์šฉ์„ ๋ณด๊ณ  ์žˆ์„ ๊ฒฝ์šฐ ์ƒˆ๋กœ์šด ๋ฉ”์„ธ์ง€๋ฅผ ํ† ์ŠคํŠธ๋ฉ”์‹œ์ง€ ํ˜•์‹์œผ๋กœ ์ œ๊ณต

11. ํ›„๊ธฐ ์„œ๋น„์Šค (๊ตฌํ˜„์ค‘)

12. ์œ ์ €์ •๋ณด์ˆ˜์ • (๊ตฌํ˜„์ค‘)

13. ํšŒ์›ํƒˆํ‡ด (๊ตฌํ˜„์ค‘)

 

 

3์ฃผ์ฐจ ํ•œ ์ผ!

3์ฃผ์ฐจ์—๋Š” ์‹ค์ „ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด์„œ ์ค‘๊ฐ„์ ๊ฒ€์„ ํ•ด์•ผํ–ˆ๋‹ค. 

์šฐ๋ฆฌ๊ฐ€ ์ตœ์†Œ ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๊ธฐ๋กœ ํ–ˆ๋˜ ๊ฒƒ๋“ค์„ ๋งˆ๋ฌด๋ฆฌํ•˜๊ณ  ์ •๋ฆฌํ–ˆ๋‹ค.

 

 

 

์ค‘๊ฐ„๋ฐœํ‘œ ์‹œ, (๋˜๋Š” ์ธํ„ฐ๋ทฐ์‹œ) ์•Œ์•„๋‘๋ฉด ์ข‹์•˜์„ ๊ฒƒ๋“ค.

- Websocket ๊ณผ socket io ์˜ ์ฐจ์ด์ ?

- ์—”์ง„์—‘์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š”?

- HTTP ์™€ HTTPS ์˜ ์ฐจ์ด์ ? (HTTPS์˜ ์ด์ ์€?)

 

 

 

 

 

2์ฃผ์ฐจ์— ํ•œ์ผ!

์™„๋ฃŒ๋œ ๋กœ๊ทธ์ธ, ํšŒ์›๊ฐ€์ž… API๋ฅผ ๋ฐฐํฌํ•˜์—ฌ ํ”„๋ก ํŠธ์™€ ์—ฐ๊ฒฐํ•˜๋Š” ์ž‘์—…์„ ํ–ˆ๋‹ค. 

์—ฌ์œ ๊ฐ€ ์ƒ๊ฒจ ํšŒ์›๊ฐ€์ž… ์ธ์ฆ์ฝ”๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(nodemailer)๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค. 

ํšŒ์›๊ฐ€์ž…์„ ํ•˜๋ ค๋ฉด ์ธ์ฆ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•˜๊ฒŒ ๋˜์„œ ๋ฒˆ๊ฑฐ๋กญ๊ฒŒ ๋ฌ๋‹ค.

 

๊ธฐํš๋‹จ๊ณ„์—์„œ socket๊ด€๋ จ ์ง€์‹์ด ์—†์œผ๋‹ˆ API๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค๊ฑฐ๋‚˜ ์ด๋ฒคํŠธ ์ด๋ฆ„์„ ์„ค์ •ํ•˜์ง€ ์•Š์•˜์—ˆ๋‹ค.

๋˜ํ•œ, mysql ์— ์ฑ„ํŒ…๊ด€๋ จํ•œ ํ…Œ์ด๋ธ”์„ ์ถ”๊ฐ€ํ–ˆ๊ณ , ์†Œ์ผ“์„ ๋ฐฐํฌ๋œ ํ™˜๊ฒฝ๊ณผ ์—ฐ๊ฒฐ์„ ์‹œ์ผฐ๋‹ค. 

 

๋ฉ”์ธํŽ˜์ด์ง€๊ฐ™์€ ๊ฒฝ์šฐ, ํ”„๋ก ํŠธ์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์†์ ์œผ๋กœ ์ถ”๊ฐ€๋˜์–ด

์ง€์†์ ์œผ๋กœ ๋ฐ”๋€Œ์—ˆ๋‹ค. ๊ทธ๋งŒํผ Mysql์„ ์ฟผ๋ฆฌ๋ฌธ์˜ Inner Join, ์ƒˆ๋กœ์šด group ์ƒ์„ฑํ•˜์—ฌ ๋‹ค์‹œ ์ ์šฉํ–ˆ๋‹ค.

 

Mysql ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ํ†ตํ•ด์„œ 1๋ถ„๋งˆ๋‹ค ๊ฒŒ์‹œํŒ ์ข…๋ฃŒ์‹œ์ ์„ ์ง€๋‚œ ๊ฒฝ์šฐ, ์™„๋ฃŒ๋œ ์ƒํƒœ๋กœ ์ž๋™ํ™” ์‹œ์ผฐ๋‹ค.

๋˜ํ•œ, ์ด๋ฉ”์ผ๋กœ ๋ณด๋‚ด์ง€๋Š” ์ธ์ฆ์ฝ”๋“œ๋Š” DB์— ์ €์žฅ๋˜๊ณ  ์žˆ์–ด 5๋ถ„๋งˆ๋‹ค ์‚ญ์ œ๋˜์–ด DB์˜ ์šฉ๋Ÿ‰์ด ๊ณผ๋ถ€ํ™” ๋˜์ง€ ์•Š๊ฒŒ ํ•˜์˜€๋‹ค.

 

 

 

2์ฃผ์ฐจ: ๊ธฐ์ˆ ์ ์ธ ์ด์Šˆ์™€ ํ•ด๊ฒฐ

์ด์Šˆ1. Mysql ์—๋Ÿฌ, Error Code: 1071. Specified key was too long; 

Mysql์—์„œ Primary Key(PK)๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ์„ค์ • ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ง์—,

์œ ์ € ๊ณ ์œ ๋ฒˆํ˜ธ, ์ด๋ฉ”์ผ, ๋‹‰๋„ค์ž„, ์‹ฌ์ง€์–ด ์ด๋ฏธ์ง€๊นŒ์ง€ ์„ค์ •์„ ํ–ˆ๋‹ค. 

 

ํ•˜์ง€๋งŒ, ์ด๋ฏธ์ง€๊ฐ™์€ ๊ฒฝ์šฐ Varchar(5000)์œผ๋กœ ์„ค์ •ํ•ด๋‘” ์ƒํƒœ์˜€๋‹ค. 

์ด PK์˜ ๋ฌธ์ž๊ธธ์ด๊ฐ€ ์ œํ•œ์ด ๋˜์–ด์žˆ๋Š”๋ฐ, ๊ทธ ๊ธธ์ด๋ณด๋‹ค ๋” ๊ธธ์–ด์ ธ์„œ ์ƒ๊ธด ๋ฌธ์ œ์˜€๋‹ค. 

์ด๋ฏธ์ง€๋ฅผ PK์—์„œ ์ œ์™ธํ•˜๋‹ˆ, ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค. 

 

 

 

 

๋กœ๊ทธ์ธ ํ›„ ๋ฉ”์ธํŽ˜์ด์ง€

 

ํ”„๋กœ์ ํŠธ: Social Study Network (SSN: ์“ด)    *ํ”„๋ก ํŠธ์—”๋“œ์™€ ์ฒซ ํ˜‘์—…ํ”„๋กœ์ ํŠธ

์„ค๋ช…: ํŒ€์›๋“ค, ํ•™๊ต์นœ๊ตฌ๋“ค๊ณผ ๊ณต๋ถ€์‹œ๊ฐ„์„ ๊ณต์œ ํ•˜๋ฉฐ ์‘์›ํ•  ์ˆ˜ ์žˆ๋Š” ์†Œ์…œ๋„คํŠธ์›Œํฌ ์‚ฌ์ดํŠธ์ž…๋‹ˆ๋‹ค.

์ œ์ž‘: 2022.04.08~2022.04.14

 

์‹œ์—ฐ์˜์ƒ: https://youtu.be/ZAMqhx5jCNU

๊นƒํ—ˆ๋ธŒ: https://github.com/ymkwon3/ssn (ํ”„๋ก ํŠธ์—”๋“œ) / https://github.com/moonhjang/miniproject_back (๋ฐฑ์—”๋“œ)

๋…ธ์…˜: https://www.notion.so/d556601ee2de4629a9a1947675f23dd6

 

 

 


์™€์ด์–ดํ”„๋ ˆ์ž„

 

 


์‚ฌ์šฉ ๊ธฐ์ˆ 
  • Server: AWS EC2 (Ubuntu 18.04 LTS)
  • Framework: Express (Node.js)
  • Database: MongoDB (Mongoose)
  • JWT (Json Web Token)
  • Crypto-js
  • CORS
  • Front-end: React

 


ํ•ต์‹ฌ ๊ธฐ๋Šฅ
  • ๋กœ๊ทธ์ธ/ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€
    • ์•„์ด๋”” ํŒจ์“ฐ์›๋“œ ์ž…๋ ฅ ๊ฐ€๋Šฅ
    • ๋กœ๊ทธ์ธ ์‹œ, ํ† ํฐ์ „๋‹ฌ (๋ชจ๋“ ํŽ˜์ด์ง€์—์„œ ํ•ด๋‹น ํ† ํฐํ™•์ธ ๊ธฐ๋Šฅ)
    • ๋นˆ์นธ ๋ฐ ์•„์ด๋”” ํ˜•์‹(4์ž์ด์ƒ, ๋Œ€์†Œ๋ฌธ์ž, ์ˆซ์ž, ํŠน์ˆ˜๋ฌธ์ž(!@#"-_)) ํ™•์ธ ๊ฐ€๋Šฅ
    • ํšŒ์›๊ฐ€์ž…์‹œ ์•„์ด๋””/๋‹‰๋„ค์ž„ ์ค‘๋ณต๊ฒ€์‚ฌ
    • ๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌํ™•์ธ ์ผ์น˜ ํ™•์ธ ๊ฐ€๋Šฅ
  • ๋ฉ”์ธํŽ˜์ด์ง€
    • ํ•ด๋‹น ์œ ์ €์™€ ์นœ๊ตฌ๋ฆฌ์ŠคํŠธ ์กฐํšŒ
    • ๊ณต๋ถ€์‹œ๊ฐ„ ์‹œ์ž‘/์ •์ง€ ๋ฒ„ํŠผ
    • ์ด ๊ณต๋ถ€์‹œ๊ฐ„ ์กฐํšŒ๊ฐ€๋Šฅ
    • ์นœ๊ตฌ ์ถ”๊ฐ€๊ฐ€๋Šฅ
    • ์นœ๊ตฌ์™€ ๊ณต๋ถ€์‹œ๊ฐ„ ์ˆœ์œ„ ํ™•์ธ๊ฐ€๋Šฅ
    • ์นœ๊ตฌ์˜ ๊ณต๋ถ€์‹œ๊ฐ„ ๋ฐ ์ ‘์† ํ™•์ธ ๊ฐ€๋Šฅ
  • ๋ฐฉ๋ช…๋ก ํŽ˜์ด์ง€
    • ๋“ฑ๋ก๋œ ์นœ๊ตฌ ๋ฐฉ๋ช…๋ก์— ์ฝ”๋ฉ˜ํŠธ ์กฐํšŒ, ์ž‘์„ฑ ๊ฐ€๋Šฅ
    • ๋ฐฉ๋ช…๋ก ์ฃผ์ธ๊ณผ ๋ฐฉ๋ช…๋ก ์ž‘์„ฑ์ž๋งŒ ์‚ญ์ œ ๊ฐ€๋Šฅ
    • ๋ณธ์ธ ๋ฐฉ๋ช…๋ก ํŽ˜์ด์ง€์—์„œ๋Š” ์ƒํƒœ๋ฉ”์„ธ์ง€ ์ˆ˜์ • ๊ฐ€๋Šฅ

 


Trouble Shooting   

โ–ถ Auth-Middleware์— ๋Œ€ํ•ด ํ”„๋ก ํŠธ ์—…๋ฌด์— ๋Œ€ํ•œ ์ดํ•ด๋ถ€์กฑํ–ˆ๋‹ค.

→ ๊ฐœ์ธํ”„๋กœ์ ํŠธ ์ง„ํ–‰์‹œ, ๋กœ๊ทธ์ธ ์‹คํ–‰์‹œ ๋กœ๊ทธ์ธ์ธ์ฆ ํ™•์ธAPI๋„ ํ•จ๊ป˜ ํ™•์ธ๋˜์—ˆ๋‹ค. ๊ทธ๋•Œ, ๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์— ์œ ์ € ์ •๋ณด๋ฅผ ๋„ฃ์–ด๋‘์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋ก ํŠธ์—์„œ ๋กœ๊ทธ์ธ์ธ์ฆ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋”ฐ๋กœ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ตณ์ด ํ•„์š”์—†์–ด ์ œ์™ธ๋ฅผ ํ–ˆ๋‹ค. ์ €์žฅ๋œ ํ† ํฐ์œผ๋กœ ๋ชจ๋“ ํŽ˜์ด์ง€์˜ ๋กœ๊ทธ์ธ ์ธ์ฆํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋™์ผํ•˜์—ฌ ๋ฌธ์ œ์—†์ด ์ž‘๋™๋˜์—ˆ๋‹ค. 

 

โ–ถ ๋กœ์ปฌ์— ์žˆ๋Š” MongoDB๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ–ˆ์ง€๋งŒ, ๋กœ์ปฌDB์˜ ๋‚ด์šฉ์„ ํ™•์ธํ•˜๋ ค๊ณ  ํ•˜๋‹ˆ ๋ฐฐํฌ๊ณผ์ •์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค. 

→ ๋กœ์ปฌDB๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  MongoDBํด๋ผ์šฐ๋“œ์— ์ง์ ‘ ์—ฐ๊ฒฐํ•˜์—ฌ ์‹คํ–‰ํ•˜์˜€๋‹ค. 

 

โ–ถ _id๋ฅผ commentid ๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด์„œ, _id๋ฅผ ๋ฐฑ์—”๋“œ์—์„œ object์—์„œ string์œผ๋กœ ๊ฐ์ฒด type์„ ๋ณ€๊ฒฝํ•ด์•ผํ•˜๋Š” ์ ์—์„œ ์–ด๋ ค์› ๋‹ค.

→ Comment ์Šคํ‚ค๋งˆ์—์„œ _id๋ฅผ commentid๋กœ ๋งŒ๋“ค์–ด string์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์ „๋‹ฌํ•˜์˜€๋‹ค. 

 

 


๊ฐœ์ธํšŒ๊ณ 

์ฒซ ํ”„๋ก ํŠธ์—”๋“œ์™€์˜ ํ˜‘๋ ฅํ”„๋กœ์ ํŠธ์˜€๋‹ค. ํ”„๋ก ํŠธ์—…๋ฌด์— ๋Œ€ํ•œ ์ง€์‹์ด ๋ถ€์กฑํ–ˆ๊ธฐ์— ํ‘œํ˜„๋ฐฉ์‹๊ณผ ์ดํ•ดํ•˜๋Š” ๋ฐฉ์‹์ด ๊ต‰์žฅํžˆ ๋‹ฌ๋ž๋‹ค. ํ”„๋กœ์ ํŠธ ์ค‘๋ฐ˜๋ถ€ํ„ฐ๋Š” ์„œ๋กœ์˜ ์—…๋ฌด๋ฅผ ์ดํ•ดํ•˜๊ณ  ๋‚˜๋‹ˆ ์ƒ๊ฐ๋ณด๋‹ค ํ”„๋กœ์ ํŠธ๊ฐ€ ๋ฌธ์ œ์—†์ด ํ’€๋ ธ๋‹ค. 

 

๊ฐœ์ธ ํ”„๋กœ์ ํŠธ์‹œ์—๋Š” ๋‚ด ์ž‘์—…์„ ์›น์‚ฌ์ดํŠธ์—์„œ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ํŽธํ–ˆ๋Š”๋ฐ, ํ˜‘๋ ฅํ•  ๋•Œ๋Š” ํ™•์ธํ•  ์ˆ˜ ์—†๋Š” ๋ทฐ๊ฐ€ ์—†์–ด์„œ ๋ถˆํŽธํ–ˆ๋‹ค. ์ฌ๋” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ทธ ์—ญํ• ์„ ๋Œ€์‹ ํ–ˆ์ง€๋งŒ, ํšŒ์›๊ฐ€์ž…์ด๋‚˜ ๋กœ๊ทธ์ธ ์‹œ ์ „๋‹ฌ๋˜๋Š” ์ •๋ณด๋ฅผ ์ง์ ‘์ž‘์„ฑํ•ด์•ผํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์› ์ง€๋งŒ ์ž˜ ์ ์‘ ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ํŠนํžˆ, ๋ชจ๋“ ํŽ˜์ด์ง€๋ฅผ auth-middleware๋กœ ์—ฐ๊ฒฐ ํ›„์—๋Š” ํ† ํฐ์ด ์—†๊ธฐ์— ์ฌ๋” ํด๋ผ์ด์–ธํŠธ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ๋‹ค. (์ดํ›„ ์•Œ์•„๋ณด๋‹ˆ, ํ—ค๋”์— ํ† ํฐ์„ ๋„ฃ์–ด ํ™•์ธํ•ด๋ณผ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ๋˜์—ˆ๋‹ค.) 

 

ํ˜‘๋ ฅํ–ˆ๋˜ ํ”„๋ก ํŠธ ๋ถ„์ด ๊ต‰์žฅํžˆ ์ž˜ํ•˜์‹œ๋˜ ๋ถ„์ด๋ผ, ๋ฐด์—”๋“œ๋กœ์„œ ๊ต‰์žฅํžˆ ๋„์›€๋„ ๋งŽ์ด ๋ฐ›์•˜๊ณ  ์ˆ˜์›”ํ•˜๊ฒŒ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ์ง„ํ–‰์‹œ, ์—ผ๋ คํ–ˆ๋˜ CORS ์ด์Šˆ๋‚˜ auth-middleware(์ธ์ฆ๋ฏธ๋“ค์›จ์–ด)์— ๋Œ€ํ•œ ์ด์Šˆ๋Š” ๊ฑฐ์˜ ์—†์—ˆ๋‹ค. ๋ฐฐํฌ ์ดˆ๋ฐ˜, ์ธ์ฆ ๋ฏธ๋“ค์›จ์–ด์— ๋Œ€ํ•œ ์•ฝ๊ฐ„์˜ ์ด์Šˆ๊ฐ€ ์žˆ์—ˆ์œผ๋‚˜ ์ฝ˜์†”์ฐ์œผ๋ฉด์„œ ์ „๋‹ฌํ•˜๊ณ  ์ „๋‹ฌ๋ฐ›๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•˜๋‹ˆ ํฐ ์ด์Šˆ์—†์ด ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค.

 

๊ต‰์žฅํžˆ ๋งŒ์กฑ์Šค๋Ÿฌ์› ๋˜ ์ ์€ ๋ชจ๋“  ๊ธฐ๋Šฅ๋“ค์ด ๋ฌธ์ œ์—†์ด ์ž˜ ์ž‘๋™ํ–ˆ๊ณ , ๋ชจ๋“  ํŒ€์›๋“ค ๋˜ํ•œ ๋งŒ์กฑ์Šค๋Ÿฝ๊ฒŒ ๋๋‚ธ ํ”„๋กœ์ ํŠธ๋ผ์„œ ๋” ์ข‹์•˜๋‹ค. ์šฐ๋ฆฌ ํŒ€์› ๋ชจ๋‘ ํฅํ•ด๋ผ!

 

ํ•ญํ•ด99 5์ฃผ์ฐจ์—๋Š” ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ๊ฐ€ ํ•จ๊ป˜ ๋ฏธ๋‹ˆํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

๊ทธ์ „์—๋„ CORS ๋ชจ๋“ˆ์„ ์„ค์น˜์— ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๋ผ๊ณ ๋งŒ ๋“ค์—ˆ๋Š”๋ฐ, 

ํ”„๋ก ํŠธ ์ž‘์—…๊ณผ ์—ฐ๊ฒฐ์‹œ ํ•„์š”ํ•œ ์ž‘์—…์ด๊ธฐ์— CORS๋ฅผ ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค.

 


 

CORS๋ž€?

 

CORS(Cross-Origin Resource Sharing), ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋ผ๊ณ  ํ•ด์„๋œ๋‹ค. 
CORS์ •์ฑ…์€ ์šฐ๋ฆฌ๊ฐ€ ๊ฐ€์ ธ์˜ค๋Š” ๋ฆฌ์†Œ์Šค๋“ค์ด ์•ˆ์ „ํ•œ์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ๊ด€๋ฌธ์ด๋‹ค. 

 

์›น ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด CORS ์ •์ฑ… ์œ„๋ฐ˜์œผ๋กœ ์ธํ•ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ฝ˜์†”์—์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฉ”์„ธ์ง€๋ฅผ ํ™•์ธํ• ์ˆ˜ ์žˆ๋‹ค.

 

CORS ๊ด€๋ จ ์ด์Šˆ๋Š” ๋ชจ๋‘ CORS ์ •์ฑ…์„ ์œ„๋ฐ˜ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ๋‹ค.

์œ„์˜ ์—๋Ÿฌ๋Š” CORS๋ฅผ ํ—ˆ์šฉํ•ด์„œ ์•„๋ฌด๋Ÿฐ ํƒˆ ์—†์ด ๋‹ค๋ฅธ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์œ ํ•ด๋‹ฌ๋ผ๋Š” ๊ถŒ๊ณ ์‚ฌํ•ญ๊ณผ ๊ฐ™์€ ๊ฒƒ์ด๋‹ค.

CORS๋ผ๋Š” ๋ฐฉ์–ด๋ง‰ ๋•๋ถ„์— ์šฐ๋ฆฌ๊ฐ€ ์ด ๊ณณ ์ € ๊ณณ์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ์•ˆ์ „ํ•˜๋‹ค๋Š” ์ตœ์†Œํ•œ์˜ ๋ณด์žฅ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

 

 

 

์ถœ์ฒ˜ (Origin) ๋ž€?

 

์„œ๋ฒ„์˜ ์œ„์น˜๋ฅผ ์˜๋ฏธํ•˜๋Š” URL์€ Protocol, Host, Port ๊นŒ์ง€๋ฅผ ์˜๋ฏธํ•œ๋‹ค. 

 

 

์›น์—๋Š” SOP(Same Origin Policy) ์™€ CORS(Cross Origin Resource Sharing) ๋‘๊ฐ€์ง€ ์ •์ฑ…์ด ์žˆ๋‹ค.

 

โ–ถ SOP(๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…) โ—€

๊ฐ™์€ ์ถœ์ฒ˜์—์„œ๋งŒ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค" ๋ผ๋Š” ๊ทœ์น™์„ ๊ฐ€์ง„ ์ •์ฑ…

 

→ URL์˜ ๊ตฌ์„ฑ์š”์†Œ ์ค‘ Protocol, Host, Port ์„ธ๊ฐ€์ง€ ๋™์ผํ•œ์ง€ ํ™•์ธํ•œ๋‹ค.

→ ๊ฐ™์€ Protocol, Host, Port์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์š”์†Œ๋Š” ๋‹ค๋ฅด๋”๋ผ๋„ ๊ฐ™์€ ์ถœ์ฒ˜๋กœ ์ธ์ •๋œ๋‹ค.

→ ๋ฆฌ์†Œ์Šค๊ฐ€ ์ž์‹ ์˜ ์ถœ์ฒ˜์™€ ๋‹ค๋ฅผ๊ฒฝ์šฐ, ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ต์ฐจ์ถœ์ฒ˜ ์š”์ฒญ์„ ์‹คํ–‰ํ•œ๋‹ค. 

์ฆ‰, Protocol, Host, Port ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด Cross Origin ์ด๋ผ๊ณ  ํ•œ๋‹ค. 

 

โ–ท ์‹ค๋ฌด์—์„œ ์ฐธ๊ณ ํ•˜์ž๋ฉด โ—

ํ”„๋ก ํŠธ ์„œ๋ฒ„์™€ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ์—ฐ๊ฒฐ์‹œ

ํ”„๋ก ํŠธ ์„œ๋ฒ„ URL์ด  http://localhost:3000,

๋ฐฑ์—”๋“œ ์„œ๋ฒ„ http://localhost:8080 ์ผ๋•Œ

 

SOP ์ •์ฑ…์— ์–ด๊ธ‹๋‚˜๊ธฐ๋•Œ๋ฌธ์—, ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์ด ๋„˜์–ด์˜ฌ ๋•Œ 

๋ธŒ๋ผ์šฐ์ €์—์„œ CORS ์ •์ฑ… ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. 

 

 

โ–ถ CORS (๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ) โ—€

์ถ”๊ฐ€ HTTP ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ํ•œ ์ถœ์ฒ˜์—์„œ ์‹คํ–‰ ์ค‘์ธ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜

์„ ํƒํ•œ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋„๋ก ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ  ์•Œ๋ ค์ฃผ๋Š” ์ฒด์ œ์ด๋‹ค. 

 

 

 

 

CORS ๋™์ž‘๋ฐฉ์‹

 

1. ํด๋ผ์ด์–ธํŠธ์—์„œ  HTTP์š”์ฒญ ํ—ค๋”์— Origin์„ ๋‹ด์•„ ์ „๋‹ฌํ•œ๋‹ค. 

 

2. ์„œ๋ฒ„๋Š” ์‘๋‹ตํ—ค์–ด์— Access-Control-Allow-Origin์„ ๋‹ด์•„ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „๋‹ฌํ•œ๋‹ค.

 

3. ํด๋ผ์ด์–ธํŠธ์—์„œ ์ž์‹ ์ด ๋ณด๋ƒˆ๋˜ ์š”์ฒญ์˜ Origin๊ณผ ์„œ๋ฒ„๊ฐ€ ๋ณด๋‚ด์ค€ Access-Control-Allow-Origin์„ ๋น„๊ตํ•œ๋‹ค. 

์ž์‹ ์ด ๋ณด๋‚ธ Origin๊ณผ ์„œ๋ฒ„๊ฐ€ ๋ณด๋‚ด์ค€ Access-Control-Allow-Origin์„ ๋น„๊ตํ•˜์—ฌ ์ฐจ๋‹จํ• ์ง€ ๋ง์ง€ ๊ฒฐ์ •ํ•œ๋‹ค. 

๋งŒ์•ฝ ์œ ํšจํ•˜์ง€ ์•Š๋‹ค๋ฉด ๊ทธ ์‘๋‹ต์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฒ„๋ฆฐ๋‹ค. 

(์œ„์˜ ๊ฒฝ์šฐ ๋‘˜๋‹ค http://localhost:3000 ์ด๊ธฐ ๋•Œ๋ฌธ์— ์œ ํšจํ•œ ๊ฒฝ์šฐ๋‹ค.)

 

 

 

 

์•„๋ž˜์˜ ๋ธ”๋กœ๊ทธ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8F

 

[WEB] ๐Ÿ“š CORS ๊ฐœ๋… ๐Ÿ’ฏ ์™„๋ฒฝ ์ •๋ฆฌ & ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ๐Ÿ‘

CORS(Cross Origin Resource Sharing) CORS ์ •์ฑ…์€ ์šฐ๋ฆฌ๊ฐ€ ๊ฐ€์ ธ์˜ค๋Š” ๋ฆฌ์†Œ์Šค๋“ค์ด ์•ˆ์ „ํ•œ์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ๊ด€๋ฌธ์ด๋‹ค. ์›น๊ฐœ๋ฐœ์„ ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์€ ์ด CORS ์ •์ฑ…์œ„๋ฐ˜์œผ๋กœ ์ธํ•ด ์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š” ์ƒํ™ฉ์„ ๋งŽ์ด๋“ค ๊ฒช์–ด๋ดค์„๊ฒƒ์ด๋ผ

inpa.tistory.com

 

์ฒซํŽ˜์ด์ง€: ๋กœ๊ทธ์ธํŽ˜์ด์ง€

 

ํ”„๋กœ์ ํŠธ : ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€

์„ค๋ช… : ๋กœ๊ทธ์ธ, ํšŒ์›๊ฐ€์ž…, ๊ฒŒ์‹œ๊ธ€ ์ฝ”๋ฉ˜ํŠธ ๋“ฑ๋ก, ์กฐํšŒ, ์ˆ˜์ •, ์‚ญ์ œ ๊ธฐ๋Šฅ๊ตฌํ˜„ ์—ฐ์Šต์„ ์œ„ํ•ด ์ œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 

์ œ์ž‘ : 2022.03.25 ~ 2022.03.31

 

์‹œ์—ฐ์˜์ƒ: https://youtu.be/sNPd6aWwgQM

๊นƒํ—ˆ๋ธŒ:  https://github.com/moonhjang/node_1

 


์‚ฌ์šฉ ๊ธฐ์ˆ 
  • Server: AWS EC2 (Ubuntu 18.04 LTS)
  • Framework: Express, Mongoose(Node.js)
  • Database: MongoDB
  • front-end: HTML5, CSS3, Javascript, Jquery, bootstrap

ํ•ต์‹ฌ ๊ธฐ๋Šฅ
  • ํšŒ์›๊ฐ€์ž…ํŽ˜์ด์ง€
  • ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ 
  • ๋กœ๊ทธ์ธ ๊ฒ€์‚ฌ
    • ์กฐํšŒํŽ˜์ด์ง€ ์ œ์™ธ, ๋กœ๊ทธ์ธ ํ•œ ๊ฒฝ์šฐ๋งŒ ๋ณผ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ
  • ๋Œ“๊ธ€
    • ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๋งŒ ๋Œ“๊ธ€ ์ถ”๊ฐ€/ ์ˆ˜์ •/ ์‚ญ์ œ

Trouble Shooting

โ–ถ ์ธ์ฆ์ด ํ•„์š”ํ•œ ํŽ˜์ด์ง€์™€ ์ธ์ฆ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์—ฐ๊ฒฐ๋˜์–ด์žˆ์ง€๋งŒ, ์•ˆ๋‚ด ์•Œ๋žŒ์ด JSํŒŒ์ผ์ด ์•„๋‹Œ HTMLํŒŒ์ผ์˜ ์•Œ๋žŒ์„ ๋„์šฐ๋Š” ์ด์Šˆ๊ฐ€์žˆ์—ˆ๋‹ค. 

→ ์ธ์ฆ ๋ฏธ๋“ค์›จ์–ด.js์™€ router.js ์ด ์ œ๋Œ€๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์•˜๋‹ค. ๋กœ๊ทธ์ธ์‹œ, ๋ฏธ๋“ค์›จ์–ด์™€ ์—ฐ๊ฒฐ๋œ ๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์— ์ž˜๋ชป๋œ ์ธ์ฆํ‚ค๊ฐ€ ๋“ค์–ด๊ฐ€๊ฒŒ ๋˜๋ฉด์„œ ์ธ์ฆ ํ‚ค๋ฅผ ์ œ๋Œ€๋กœ ์ „๋‹ฌํ•ด์ฃผ์ง€ ๋ชปํ•˜๋ฉด์„œ ์ƒ๊ฒจ๋‚œ ์ด์Šˆ์˜€๋‹ค. ์—ฐ๊ฒฐ์ด ์ž˜ ๋˜๋ฉด์„œ ์•Œ๋ฆผ์ด์Šˆ๋Š” ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค. 

 

โ–ถ ๋Œ“๊ธ€ ์ถ”๊ฐ€์‹œ, mongoDB์˜ subdocument์ด์šฉ๋ฐฉ๋ฒ•์œผ๋กœ ๋Œ“๊ธ€์„ ์ถ”๊ฐ€ํ•˜์˜€๋‹ค. ์ด์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ์กฐํšŒ๋ฅผ ํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์˜ค๋ฅ˜๋กœ ์ž‘๋™์ด ๋˜์ง€์•Š์•˜๋‹ค.

→ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์˜ค๋ฅ˜๋ฅผ ์žก๊ธฐ์œ„ํ•ด์„œ Try-Catch๋ฌธ์„ ์ด์šฉํ•˜์—ฌ ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค.

 

 

+ ์ง€๋‚œ์ฃผ ์ž‘์—…์—์„œ ์•„์‰ฌ์› ๋˜ ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ ๋ฐ, env ํŒŒ์ผ๊ณผ .gitignore์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜์˜€๋‹ค.

 

Node.js ํ”„๋กœ์ ํŠธ๋ฅผ 

ํ™œ์„ฑํ™”์‹œํ‚ค๋ฉด์„œ ์ž๋™์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š”

"package.json"

์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ณ ์ž ํ•œ๋‹ค.


npm ์ด๋ž€?

 

npm์€ Node Package Manager์˜ ์•ฝ์–ด๋กœ, ๋ช…์นญ ๊ทธ๋Œ€๋กœ ๋…ธ๋“œ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์ด๋‹ค.

 

๋…ธ๋“œ๊ฐ€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ”„๋กœ๊ทธ๋žจ์„ ์ปดํ“จํ„ฐ์—์„œ๋„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ”„๋กœ๊ทธ๋žจ์€ ํŒจํ‚ค์ง€๋กœ npm์— ๋“ฑ๋ก๋˜์–ด ์žˆ์œผ๋ฉฐ

ํŠน์ • ๊ธฐ๋Šฅ์˜ ํŒจํ‚ค์ง€๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด npm ์—์„œ ์ฐพ์•„ ์„ค์น˜ํ•˜๋ฉด ๋œ๋‹ค.

 

 

 

package.json

ํ”„๋กœ์ ํŠธ์— ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜๋‹ค๋ณด๋ฉด ํŒจํ‚ค์ง€๊ฐ€ ์–ด๋งˆ์–ด๋งˆํ•ด์ง„๋‹ค.
์‚ฌ์šฉํ•˜๋Š” ํŒจํ‚ค์ง€๋Š” ์ €๋งˆ๋‹ค ๊ณ ์œ ํ•œ ๋ฒ„์ „์ด ์žˆ์œผ๋ฉฐ,
๋™์ผํ•œ ๋ฒ„์ „์„ ์„ค์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ์ˆ˜ ์žˆ๋‹ค. 

์ด๋•Œ ์„ค์น˜ํ•œ ํŒจํ‚ค์ง€์˜ ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•˜๋Š” ํŒŒ์ผ์„
package.json ์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

 

 

package.json ์„ค์น˜ํ•˜๊ธฐ

ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ํด๋” ๋‚ด๋ถ€์— ๋ฌด์กฐ๊ฑด package.json๋ถ€ํ„ฐ ๋งŒ๋“ค๊ณ  ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค!

npm init -y

* -y : ๋ชจ๋“  ํ•ญ๋ชฉ์— Yes๋ฅผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

ํ”„๋กœ์ ํŠธ ์ด๋ฆ„, ์„ค๋ช… ๋“ฑ์„ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, 

'npm init'๋กœ ์‹คํ–‰์‹œํ‚ค๊ณ  ์ฝ˜์†”์ฐฝ์—์„œ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

์•„๋ž˜์˜ ํ˜•์‹์œผ๋กœ package.json ๋ฏธ๋ฆฌ๋ณด๊ธฐ๊ฐ€ ๋‚˜์˜จ๋‹ค.

{
  "name": "ํ”„๋กœ์ ํŠธ ์ด๋ฆ„",
  "version": "ํ”„๋กœ์ ํŠธ ๋ฒ„์ „",
  "description": "ํ”„๋กœ์ ํŠธ ์„ค๋ช…",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "์ž‘์„ฑ์ž ์ด๋ฆ„",
  "license": "ISC",
  }
}

 

 

 

package.json ์ž‘์„ฑ์‹œ ์•Œ์•„๋‘๊ธฐ

package name :

ํŒจํ‚ค์ง€ ์ด๋ฆ„์œผ๋กœ Package.json์˜ name ์†์„ฑ์— ์ €์žฅ๋œ๋‹ค. 

 

version :

ํŒจํ‚ค์ง€ ๋ฒ„์ „์€ SemVer์˜ ๋ฐฉ์‹์˜ ๋ฒ„์ „ ๋„˜๋ฒ„๋ง์„ ๋”ฐ๋ผ ํ•ญ์ƒ ์„ธ์ž๋ฆฌ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. 

 

package.json์— ๊ฐ€์žฅ ์ค‘์š”ํ•œ ํ•ญ๋ชฉ์€ "name" ๊ณผ "version" ์ด๋‹ค.

์ด 2๊ฐ€์ง€ ํ•ญ๋ชฉ์„ ํ†ตํ•ด ํŒจํ‚ค์ง€ ๊ณ ์œ ์„ฑ์„ ํŒ๋ณ„ํ•˜๊ฒŒ ๋œ๋‹ค.

ํ•„์ˆ˜ ํ•ญ๋ชฉ์ด๋ฉฐ, ํ•ด๋‹น ๋‚ด์šฉ์ด ์—†์œผ๋ฉด ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ ํ•  ์ˆ˜ ์—†๋‹ค.

 

 

description :

๋ฌธ์ž์—ด๋กœ ๊ธฐ์ž…ํ•ด์•ผํ•˜๋ฉฐ, 

npm search๋กœ ๊ฒ€์ƒ‰๋œ ๋ฆฌ์ŠคํŠธ์— ํ‘œ์‹œ๋˜์–ด ๋งŒ๋“ค์–ด์ง„ ํŒจํ‚ค์ง€๋ฅผ ์ฐพ๊ณ  ์ดํ•ดํ•˜๋Š” ๋„์›€์„ ์ค€๋‹ค. 

 

entry point :

์ž๋ฐ”์Šคํฌ๋ฆผํŠธ ์‹คํ–‰ํŒŒ์ผ ์ง„์ž…์ . ๋ณดํ†ต ๋งˆ์ง€๋ง‰์œผ๋กœ module.exports๋ฅผ ํ•˜๋Š” ํŒŒ์ผ์„ ์ง€์ •ํ•œ๋‹ค. 

package.json์˜ main์†์„ฑ์— ์ €์žฅ๋œ๋‹ค.

 

test commend

์ฝ”๋“œ ํ…Œ์ŠคํŠธ ์‹œ ์ž…๋ ฅํ•˜๋Š” ๋ช…๋ น์–ด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

package.json scripts ์†์„ฑ์•ˆ์˜ test ์†์„ฑ์— ์ €์žฅ๋œ๋‹ค.

 

git repository :

์ฝ”๋“œ๋ฅผ ์ €์žฅํ•ด๋‘” ๊นƒ ์ €์žฅ์†Œ ์ฃผ์†Œ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

์†Œ์Šค์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋ฉด ์‚ฌ์šฉ์ž๋“ค์ด ์ด ์ €์žฅ์†Œ์— ๋ฐฉ๋ฌธ์— ๋ฌธ์ œ๋ฅผ ์ œ๊ธฐํ•˜๊ฑฐ๋‚˜

์ฝ”๋“œ ์ˆ˜์ •๋ณธ์„ ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋‹ค. package.json repository ์†์„ฑ์— ์ €์žฅ๋œ๋‹ค.

 

keywords : ํ‚ค์›Œ๋“œ๋ฅผ ๋ฌธ์ž์—ด ๋ฐฐ์—ด๋กœ ์„ค๋ช…๋˜๋ฉฐ,

npm search๋กœ ๊ฒ€์ƒ‰๋œ ๋ฆฌ์ŠคํŠธ์— ํ‘œ์‹œ๋˜์–ด ๋งŒ๋“ค์–ด์ง„ ํŒจํ‚ค์ง€๋ฅผ ์ฐพ๊ณ  ์ดํ•ดํ•˜๋Š” ๋„์›€์„ ์ค€๋‹ค.

 

bugs :

ํ”„๋กœ์ ํŠธ์˜ ์ด์Šˆ์™€ ๋ฒ„๊ทธ ํŠธ๋ ˆํ‚น์„ ๋ณผ์ˆ˜์žˆ๋Š” url ๋˜๋Š” ์ด์Šˆ๋ฅผ ์•Œ๋ฆด email ์ฃผ์†Œ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. 

ํŒจํ‚ค์ง€ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ์‹œ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

 

 license

ํŒจํ‚ค์ง€ ์‚ฌ์šฉ์ž๋“ค์ด ๋งŒ๋“ค์–ด์ง„ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ป๊ฒŒ ๊ถŒํ•œ์„ ์–ป๊ณ ,

์–ด๋–ค ๊ธˆ๊ธฐ ์‚ฌํ•ญ์ด ์žˆ๋Š”์ง€ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ๋ผ์ด์„ผ์Šค๋ฅผ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค. 

 

dependencies :

ํŒจํ‚ค์ง€ ์„ค์น˜์‹œ, ํŒจํ‚ค์ง€ ์ด๋ฆ„๊ณผ ํ•จ๊ป˜ ์„ค์น˜๋œ ๋ฒ„์ „์ด ์ €์žฅ๋œ๋‹ค.  

 

devDenpendencies :

ํŒจํ‚ค์ง€ ๋ชจ๋“ˆ์„ ์ด์šฉํ•˜๋Š” ์‚ฌ๋žŒ์ด๋ผ๋ฉด, ํŒจํ‚ค์ง€ ํ…Œ์ŠคํŠธ ๋ฐ ๋ฌธ์„œ ์ž‘์„ฑ์— ์‚ฌ์šฉ๋˜๋Š”

์™ธ๋ถ€ ํ”„๋ ˆ์ž„ ์›Œํฌ๋Š” ๋‹ค์šด๋กœ๋“œ๋ฅผ ์›ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. 

์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ, devDependencies ๊ฐ์ฒด์— ๋””ํŽœ๋˜์‹œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋‹ค.  

 

 

 

 

๋” ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ์•„๋ž˜์˜ ๋งํฌ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

https://docs.npmjs.com/cli/v8/configuring-npm/package-json

๊ฒŒ์‹œ๊ธ€ ํŽ˜์ด์ง€

 

ํ”„๋กœ์ ํŠธ: ๊ฒŒ์‹œ๊ธ€ ํŽ˜์ด์ง€

์„ค๋ช…: ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์กฐํšŒ, ๋“ฑ๋ก, ์ˆ˜์ • ์‚ญ์ œ์˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ์—ฐ์Šต์„ ์œ„ํ•ด ์ œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 

์ œ์ž‘: 2022.03.18 ~2022.03.24

 

์‹œ์—ฐ์˜์ƒ: https://youtu.be/hJivoIls7AQ

๊นƒํ—ˆ๋ธŒ: https://github.com/moonhjang/node_1

 


 

์‚ฌ์šฉ ๊ธฐ์ˆ 
  • Server: AWS EC2 (Ubuntu 18.04 LTS)
  • Framework: Express, Mongoose (Node.js)
  • Database: MongoDB
  • front-end: HTML5, CSS3, Javascript, Jquery, bootstrap

 


 

ํ•ต์‹ฌ ๊ธฐ๋Šฅ
  • ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก์กฐํšŒํŽ˜์ด์ง€
    • ์ œ๋ชฉ, ์ž‘์„ฑ์ž๋ช…, ์ž‘์„ฑ๋‚ ์งœ ์กฐํšŒ
    • ์ž‘์„ฑ ๋‚ ์งœ ๊ธฐ์ค€์œผ๋กœ ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ
    • ํŠน์ • ๊ฒŒ์‹œ๊ธ€ ์„ ํƒ์‹œ ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒํŽ˜์ด์ง€๋กœ ์ด๋™
  • ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑํŽ˜์ด์ง€
    • ์ œ๋ชฉ, ์ž‘์„ฑ์ž๋ช…, ๋น„๋ฐ€๋ฒˆํ˜ธ, ์ž‘์„ฑ๋‚ด์šฉ ์ž…๋ ฅ ํ›„ ์ €์žฅ
    • ์ž…๋ ฅ๋ž€์ด ๋น„์–ด์žˆ์„ ์‹œ, "์ž…๋ ฅํ•ด์ฃผ์„ธ์š”" ์•Œ๋žŒ๋„์šฐ๊ธฐ
  • ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒํŽ˜์ด์ง€
    • ์ œ๋ชฉ, ์ž‘์„ฑ์ž๋ช…, ์ž‘์„ฑ๋‚ ์งœ, ์ž‘์„ฑ ๋‚ด์šฉ ์กฐํšŒ
  • ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ •/์‚ญ์ œํŽ˜์ด์ง€
    • ์ž…๋ ฅ๋ž€์ด ๋น„์–ด์žˆ์„ ์‹œ, "์ž…๋ ฅํ•ด์ฃผ์„ธ์š”" ์•Œ๋žŒ๋„์šฐ๊ธฐ
    • ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•  ์‹œ, ์ˆ˜์ •/์‚ญ์ œ ๊ฐ€๋Šฅ
    • ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ์‹œ, "๋น„๋ฐ€๋ฒˆํ˜ธ ๋ถˆ์ผ์น˜" ์•Œ๋žŒ๋„์šฐ๊ธฐ

 


 

Trouble Shooting 

 

Node.js์˜ ์‹œ์Šคํ…œ์„ ์™„์ „ํžˆ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ์ฑ„ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. 1~2์ผ์ฐจ์€ Node.js์— ๋Œ€ํ•ด์„œ ๋ฐฐ์› ๊ณ , 3~4์ผ์ฐจ์—๋Š” ์›น์‚ฌ์ดํŠธ์˜ ๋ฐฑ์—”๋“œ ์—ญํ• ์— ์ง‘์ค‘ํ•˜์˜€๋‹ค. 5~7์ผ์ฐจ์—๋Š” ํ”„๋ก ํŠธ์™€ ๋ฐฑ์—”๋“œ์— ์—ฐ๊ฒฐ์— ์ง‘์ค‘ํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜์˜€๋‹ค. Node.js์˜ ์งง์€ ์ดํ•ด์™€ ์งง์€ ์‹œ๊ฐ„๋™์•ˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜์˜€๊ธฐ์— ์™„์„ฑ๋„๋Š” ๋–จ์–ด์ง€์ง€๋งŒ, ๋ชฉํ‘œํ•˜๋Š” ๊ธฐ๋Šฅ๊ตฌํ˜„์€ ์™„์„ฑํ•˜์˜€๋‹ค. 

 

โ–ถ DB์ €์žฅ์‹œ, ๊ฐ ํฌ์ŠคํŒ…์— ๋Œ€ํ•ด์„œ postsid๋ฅผ ์ง€์ •ํ–ˆ๋Š”๋ฐ, 1๊ฐœ ์ดํ›„๋กœ postsid ์ค‘๋ณต๊ด€๋ จ ์—๋Ÿฌ๊ฐ€ ๋‚˜์˜ค๋ฉด์„œ ์ €์žฅ๋˜์ง€ ์•Š์•˜๋‹ค.

postsid๋ฅผ ์ž‘์„ฑ๋‚ ์งœ์— ์—ฐ๊ด€ํ•ด์„œ ๋„˜๋ฒ„๋ง ํ•ด์ฃผ๋‹ˆ ๋ฌธ์ œ์—†์ด ์ €์žฅ๋จ

 

โ–ถ MongoDB๋ฅผ ์ด์šฉํ–ˆ์„๋•Œ์™€ ๋‹ค๋ฅด๊ฒŒ Mongoose๋Š” ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์—†์–ด๋„ Robo3T์—์„œ DB๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.  ํ•˜์ง€๋งŒ, ๋„๋ฉ”์ธ๊ณผ ์—ฐ๊ฒฐ ํ›„ Robo3T์— ์ €์žฅ๋œ ๋‚ด์šฉ๊ณผ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š๊ณ  ์ž์ฒด DB๋ฅผ ๋งŒ๋“ค์–ด ์‹คํ–‰๋˜์—ˆ๋‹ค. ์–ด๋””์— ์ €์žฅ๋˜๊ณ  ์žˆ๋Š”์ง€ ์•„์ง๋„ ์˜๋ฌธ์ด ๋“ ๋‹ค. DB๋‚ด์šฉ ์กฐํšŒ๋‚˜ ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ๋ถˆํŽธํ•  ๊ฒƒ๊ฐ™์•„ ํ”„๋กœ์ ํŠธ ๋งˆ์ง€๋ง‰๋‚  ์†Œ์œ ํ•˜๊ณ ์žˆ๋Š” MongoDB๋กœ ๊ฒฝ๋กœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๊ณ  ํ•˜์˜€์Œ.

→ ๋„๋ฉ”์ธ์— ์—ฐ๊ฒฐ๋œ ์ž์ฒด DB๋Š” ๊ป๋‹ค ์ผœ๋„ ๊ฐ™์€ DB์— ์—ฐ๊ฒฐ๋˜์–ด์„œ ์•„์ง๋„ ์‚ฌ์šฉํ•ด๋„๋˜๋Š”์ง€ ์˜๋ฌธ์ด ๋“ฆ.

ํ•ด๋‹น๋ถ€๋ถ„์€ ์ถ”ํ›„ ์Šคํ„ฐ๋””๊ฐ€ ํ•„์š”ํ•จ.

 

โ–ถ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ €์žฅ์‹œ, ์•”ํ˜ธํ™”์ฒ˜๋ฆฌ๊ฐ€ ์–ด๋ ค์› ๋‹ค.

→ ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ์‹œ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋กœ ์ €์žฅ์ด ๊ฐ€๋Šฅํ•จ. ํ•˜์ง€๋งŒ, ์‚ญ์ œ ๋ฐ ์ˆ˜์ •ํŽ˜์ด์ง€์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ์‹œ ์ž‘์„ฑ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•”ํ˜ธํ™” ์‹œํ‚จ๊ฒƒ๊ณผ ์ €์žฅ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ–ˆ์„๋•Œ ๊ฐ™์€ ๊ฐ’์ด ์•„๋‹˜. ๋˜ํ•œ, ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ '$'์™€ ๊ฐ™์€ ๊ธฐํ˜ธ๊ฐ€ ์žˆ์–ด Schema์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” 'String' ์ง€์ •๋œ ์ƒํƒœ์™€ ๋‹ฌ๋ผ์„œ ์˜ค๋ฅ˜๋ฅผ ๋ƒ„. ๋˜ํ•œ, ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ถฉ๋ถ„ํ•œ ์‹œ๊ฐ„์ด ์—†์–ด์„œ ์ถ”ํ›„ ๋‹ค์‹œ ๋„์ „ํ•  ์˜ˆ์ •์ž„.

 

 

 

 

- CSS ์‚ฌ์šฉํ•˜๊ธฐ (๊ตฌ๊ธ€์›นํฐํŠธ, ์ด๋ฏธ์ง€ ๋„ฃ๊ธฐ)
- ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์‚ฌ์šฉํ•˜๊ธฐ
- ํฌ์ŠคํŒ…๋ฐ•์Šค ๋งŒ๋“ค๊ธฐ

 

 

 

 

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
            crossorigin="anonymous"></script>

    <title>์ŠคํŒŒ๋ฅดํƒ€์ฝ”๋”ฉํด๋Ÿฝ | ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ์—ฐ์Šตํ•˜๊ธฐ</title>
   <link href="https://fonts.googleapis.com/css2?family=Poor+Story&display=swap" rel="stylesheet">
    <style>
        *{
            font-family: 'Poor Story', cursive;
        }
        .mytitle {

            max-width: 100%;
            height: 600px;

            background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url("https://img.vogue.co.kr/vogue/2021/12/style_61c299401f4b3.jpeg");
            background-position: center;
            background-size: cover;

            color: white;

            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }
        .card {
            max-width: 95%;
            width: 500px;
            height:100px;

            margin: 10px auto 0px auto;
        ;
        }
        .mypost {
            max-width: 95%;
            width: 500px;
            height: 300px;

            background-color: transparent;
            color: black;
            border-radius: 5px;

            border: 1px solid grey;

            margin: 20px auto;
            padding: 20px;
        }
        .mypost > button {
            margin: 20px auto;
        }
    </style>
</head>

<body>
    <div class="mytitle">
        <h1>์•„์ด์œ  ํŒฌ๋ช…๋ก</h1>
    </div>

    <div class="mypost">
        <div class="form-floating mb-3">
          <input type="email" class="form-control" id="floatingInput" placeholder="๋‹‰๋„ค์ž„">
          <label for="floatingInput">๋‹‰๋„ค์ž„</label>
        </div>

        <div class="form-floating">
            <textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea2"
                      style="height: 100px"></textarea>
            <label for="floatingTextarea2">์‘์›๋Œ“๊ธ€</label>
        </div>

        <button type="button" class="btn btn-dark">์‘์›๋‚จ๊ธฐ๊ธฐ</button>
    </div>

    <div class="card">
      <div class="card-body">
        <blockquote class="blockquote mb-0">
          <p>์•จ๋ฒ” ๋„ˆ๋ฌด ์ข‹์•„์š”!</p>
          <footer class="blockquote-footer">์•„์ด๋Ÿฌ๋ธŒ์œ </cite></footer>
        </blockquote>
      </div>
    </div>
    <div class="card">
      <div class="card-body">
        <blockquote class="blockquote mb-0">
          <p>์•จ๋ฒ” ๋„ˆ๋ฌด ์ข‹์•„์š”!</p>
          <footer class="blockquote-footer">์•„์ด๋Ÿฌ๋ธŒ์œ </cite></footer>
        </blockquote>
      </div>
    </div>
    <div class="card">
      <div class="card-body">
        <blockquote class="blockquote mb-0">
          <p>์•จ๋ฒ” ๋„ˆ๋ฌด ์ข‹์•„์š”!</p>
          <footer class="blockquote-footer">์•„์ด๋Ÿฌ๋ธŒ์œ </cite></footer>
        </blockquote>
      </div>
    </div>

</body>

</html>

+ Recent posts