๐Ÿ˜Žย ์•Œ๊ณ  ์“ฐ์ž, JWT(Json Web Token).

๊น€๋ฏผ์ฃผยท2023๋…„ 8์›” 6์ผ
13
post-thumbnail

๋“ค์–ด๊ฐ€๊ธฐ

์•ˆ๋“œ๋กœ์ด๋“œ ๊ฐœ๋ฐœ์ž์ธ ๋‚˜๋Š” ๋กœ๊ทธ์ธ์„ ๊ตฌํ˜„ํ•  ๋•Œ ๋‹น์—ฐํ•˜๊ฒŒ jwt ํ† ํฐ ์ธ์ฆ๋ฐฉ์‹์„ ์จ์™”์—ˆ๋‹ค. jwt ํ† ํฐ์ด ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑ๋˜์–ด์žˆ๋Š”์ง€ ์™œ jwt ํ† ํฐ์„ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์„ ํ•˜์ง€ ์•Š์•˜์—ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค.. ๊ฐœ๋ฐœ์ž๋กœ์„œ ์„ฑ์žฅํ•  ์ž์„ธ๊ฐ€ ์•ˆ๋˜์–ด์žˆ์—ˆ๋‹ค.๐Ÿ˜ข ๊ณผ๊ฑฐ์˜ ๋‚˜๋ฅผ ๋ฐ˜์„ฑํ•˜๊ณ , ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๊ณต๋ถ€ํ•œ ๊ฒƒ์„ ๊ณต์œ ํ•˜๊ณ ์ž jwt ํ† ํฐ์— ๊ด€๋ จ๋œ ๊ธ€์„ ์ž‘์„ฑํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

JWT ํ† ํฐ์ด๋ž€?

JWT(Json Web Token)์€ Json ๊ฐ์ฒด์— ์ธ์ฆ์— ํ•„์š”ํ•œ ์ •๋ณด๋“ค์„ ๋‹ด์€ ํ›„ ๋น„๋ฐ€ํ‚ค๋กœ ์„œ๋ช…ํ•œ ํ† ํฐ์œผ๋กœ, ์ธํ„ฐ๋„ท ํ‘œ์ค€ ์ธ์ฆ ๋ฐฉ์‹์ด๋‹ค. ๊ณต์‹์ ์œผ๋กœ ์ธ์ฆ(Authentication) & ๊ถŒํ•œํ—ˆ๊ฐ€(Authorization) ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

์—ฌ๊ธฐ์„œ ์ผ๋ฐ˜ ๋กœ๊ทธ์ธ ๊ณผ์ •๊ณผ ์ธ์ฆ ๋ฐฉ์‹์„ ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ๋ฐ”๋กœ jwt ํ”„๋กœ์„ธ์Šค๋ฅผ ์‚ดํŽด๋ณด์ž.

JWT ํ”„๋กœ์„ธ์Šค

  1. ์‚ฌ์šฉ์ž๊ฐ€ ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ˜น์€ ์†Œ์…œ ๋กœ๊ทธ์ธ์„ ์ด์šฉํ•˜์—ฌ ์„œ๋ฒ„์— ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.
  2. ์„œ๋ฒ„๋Š” ๋น„๋ฐ€ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด json ๊ฐ์ฒด๋ฅผ ์•”ํ˜ธํ™”ํ•œ JWT ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•œ๋‹ค.
  3. JWT๋ฅผ ํ—ค๋”์— ๋‹ด์•„ ํด๋ผ์ด์–ธํŠธ์— ๋ณด๋‚ธ๋‹ค.

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ JWT๋ฅผ ๋ฐœ๊ธ‰๋ฐ›๊ธฐ๊นŒ์ง€์˜ (๋กœ๊ทธ์ธ ์ „)๊ณผ์ •์ด๋‹ค. ๋กœ๊ทธ์ธ ์ดํ›„์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณผ์ •์ด ์ด๋ฃจ์–ด์ง„๋‹ค.

  1. ํด๋ผ์ด์–ธํŠธ๋Š” JWT๋ฅผ ๋กœ์ปฌ์— ์ €์žฅํ•ด๋†“๋Š”๋‹ค.
  2. API ํ˜ธ์ถœ์„ ํ•  ๋•Œ๋งˆ๋‹ค header์— JWT๋ฅผ ์‹ค์–ด ๋ณด๋‚ธ๋‹ค.
  3. ์„œ๋ฒ„๋Š” ํ—ค๋”๋ฅผ ๋งค๋ฒˆ ํ™•์ธํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ์‹ ๋ขฐํ• ๋งŒํ•œ์ง€ ์ฒดํฌํ•˜๊ณ , ์ธ์ฆ์ด ๋˜๋ฉด API์— ๋Œ€ํ•œ ์‘๋‹ต์„ ๋ณด๋‚ธ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๋กœ๊ทธ์ธ ํ›„์— ์™œ ๋งค๋ฒˆ JWT๋ฅผ ํ—ค๋”์— ๋„ฃ์–ด์„œ ๋ณด๋‚ด์•ผ ํ• ๊นŒ? ๋น„ํšจ์œจ์ ์ด๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค ์ˆ˜ ์žˆ๋‹ค. ๋งค๋ฒˆ ์ธ์ฆ ๊ณผ์ •์„ ๊ฑฐ์ณ์•ผํ•˜๋Š” ์ด์œ ๋Š” HTTP์˜ ํŠน์„ฑ ๋•Œ๋ฌธ์ด๋‹ค.

HTTP์˜ ํŠน์„ฑ

Connectionless : ํ•œ ๋ฒˆ ํ†ต์‹ ์ด ์ด๋ค„์ง€๊ณ  ๋‚œ ํ›„์— ์—ฐ๊ฒฐ์ด ๋ฐ”๋กœ ๋Š์–ด์ง„๋‹ค
Stateless : ์ด์ „ ์ƒํƒœ๋ฅผ ์œ ์ง€/๊ธฐ์–ตํ•˜์ง€ ์•Š๋Š”๋‹ค

์ธํ„ฐ๋„ท์„ ์‚ฌ์šฉํ•˜๋Š” ์šฐ๋ฆฌ๋Š” HTTP ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•ด์„œ ํ†ต์‹ ์„ ํ•œ๋‹ค. ์›น ํŽ˜์ด์ง€๋ฅผ ์—ด ๋•Œ๋„, ํ•ธ๋“œํฐ ์–ดํ”Œ์„ ์‚ฌ์šฉํ•  ๋•Œ๋„, ํด๋ผ์šฐ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋„ HTTP ํ†ต์‹ ์œผ๋กœ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋Š”๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋Ÿฐ HTTP๋Š” connectionlessํ•˜๊ณ  statelessํ•˜๋‹ค๋Š” ํŠน์„ฑ์ด ์žˆ๋‹ค. ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜๋ฉด ํ•œ ๋ฒˆ ํ†ต์‹ ์ด ์ผ์–ด๋‚˜๊ณ  ๋‚˜๋ฉด ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง„๋‹ค๋Š” ๊ฒƒ์ด๊ณ , ๋‹ค์‹œ ์—ฐ๊ฒฐํ•ด๋„ ์ด์ „ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜์ง€ ์•Š์•„ ๊ณผ๊ฑฐ์— ์–ด๋–ค ์ •๋ณด๋ฅผ ๋ณด๋ƒˆ์—ˆ๋Š”์ง€ ๊ธฐ์–ตํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰, ํ™”๋ฉด์„ ์ด๋™ํ•˜๋ฉฐ ์ƒˆ๋กœ์šด API๋ฅผ ์š”์ฒญํ•˜๋ฉด ๋‹ค์‹œ ์‹ ๋ขฐํ• ๋งŒํ•œ ์‚ฌ์šฉ์ž์ธ์ง€ ์ธ์ฆํ•˜๋Š” ๊ณผ์ •์„ ๊ฑฐ์ณ์•ผํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๋งค๋ฒˆ ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ฆํ•˜๋Š” ๊ณผ์ •์€ ๊ท€์ฐฎ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํ†ต์‹ ์ด ๋Š๋ ค์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋Š ์ •๋„ ๊ธฐ๊ฐ„๋™์•ˆ ์žฌ์ธ์ฆ ํ•˜์ง€ ์•Š์•„๋„ ๋˜๋„๋ก(๋กœ๊ทธ์ธ์ด ์œ ์ง€๋˜๋„๋ก) ๋งŒ๋“  ๊ฒƒ์ด Access Token์ด๋‹ค.

Access Token์€ jwt ํ† ํฐ์˜ ์ผ์ข…์ด๊ธฐ์— ๋จผ์ € jwt ๊ตฌ์กฐ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๊ณ  ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ Access token๊ณผ Refresh token์— ๋Œ€ํ•ด ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ๋‹ค.

JWT์˜ ๊ตฌ์กฐ

JWT๋Š” Header, Payload, Signature 3๊ฐœ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

๐Ÿ“Œย Header

  • alg : Signature์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜
  • typ : ํ† ํฐ ํƒ€์ž…

Signature์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋Œ€ํ‘œ์ ์œผ๋กœ RS256(๊ณต๊ฐœํ‚ค/๊ฐœ์ธํ‚ค)์™€ HS256(๋น„๋ฐ€ํ‚ค(๋Œ€์นญํ‚ค))๊ฐ€ ์žˆ๋‹ค. ์ด ๋ถ€๋ถ„์€ auth0 ๊ณต์‹ ๋ฌธ์„œ์—์„œ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ฃผ๊ณ  ์žˆ๋‹ค.

๐Ÿ“Œย Payload

์‚ฌ์šฉ์ž ์ •๋ณด์˜ ํ•œ ์กฐ๊ฐ์ธ ํด๋ ˆ์ž„(claim)์ด ๋“ค์–ด์žˆ๋‹ค.

  • sub : ํ† ํฐ ์ œ๋ชฉ(subject)
  • aud : ํ† ํฐ ๋Œ€์ƒ์ž(audience)
  • iat : ํ† ํฐ์ด ๋ฐœ๊ธ‰๋œ ์‹œ๊ฐ (issued at)
  • exp : ํ† ํฐ์˜ ๋งŒ๋ฃŒ ์‹œ๊ฐ (expired)

๐Ÿ“Œย Signature

Signature๋Š” ํ—ค๋”์™€ ํŽ˜์ด๋กœ๋“œ์˜ ๋ฌธ์ž์—ด์„ ํ•ฉ์นœ ํ›„์—, ํ—ค๋”์—์„œ ์„ ์–ธํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ key๋ฅผ ์ด์šฉํ•ด ์•”ํ˜ธํ•œ ๊ฐ’์ด๋‹ค.

Header์™€ Payload๋Š” ๋‹จ์ˆœํžˆ Base64url๋กœ ์ธ์ฝ”๋”ฉ๋˜์–ด ์žˆ์–ด ๋ˆ„๊ตฌ๋‚˜ ์‰ฝ๊ฒŒ ๋ณตํ˜ธํ™”ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, Signature๋Š” key๊ฐ€ ์—†์œผ๋ฉด ๋ณตํ˜ธํ™”ํ•  ์ˆ˜ ์—†๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ณด์•ˆ์ƒ ์•ˆ์ „ํ•˜๋‹ค๋Š” ํŠน์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

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

๐Ÿ˜‹ ์ง์ ‘ ๋ง›๋ณด๊ธฐ

https://jwt.io/ ์— ๋“ค์–ด๊ฐ€ token ๊ฐ’์„ ์ž…๋ ฅํ•˜๋ฉด ํ˜„์žฌ ์ž์‹ ์ด ์‚ฌ์šฉ์ค‘์ธ jwt ํ† ํฐ์ด ์–ด๋–ค ๊ตฌ์กฐ๋กœ ๋˜์–ด์žˆ๋Š”์ง€ ์‰ฝ๊ฒŒ ๋ˆˆ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ์ค„๊ณง ์‚ฌ์šฉํ–ˆ๋˜ ํ† ํฐ์˜ ๊ตฌ์กฐ๋ฅผ ๋“œ๋””์–ด ์ฒ˜์Œ ์˜์ ‘ํ–ˆ๋‹ค..ใ…Ž
์ฐธ๊ณ ๋กœ exp์™€ iat์˜ ๊ฒฝ์šฐ DateTime์— ๋งˆ์šฐ์Šค๋ฅผ ๊ฐ–๋‹ค ๋Œ€๋ฉด ์ •ํ™•ํ•œ ๋‚ ์งœ์™€ ์‹œ๊ฐ„์ด ๋ฐ”๋กœ ๋‚˜์˜จ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ ๊นจ๋‹ฌ์•„์•ผํ•  ๊ฒƒ์ด ์žˆ๋‹ค. header์™€ payload๋Š” ์ด๋ ‡๊ฒŒ ๋ˆ„๊ตฌ๋‚˜ ์‰ฝ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ถ€๋ถ„๋“ค์—๋Š” ์ค‘์š”ํ•œ ์ •๋ณด๋ฅผ ๋‹ด์œผ๋ฉด ์•ˆ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค!

์žฅ๋‹จ์ 

๐Ÿ“Œย ์žฅ์ 

  • ๋กœ์ปฌ์— ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„ ์šฉ๋Ÿ‰์— ์˜ํ–ฅ์„ ๋ผ์น˜๊ฑฐ๋‚˜ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.
  • ๋ณด๋‹ค ์•ˆ์ „ํ•˜๋‹ค. (๊ณต๊ฐœํ‚ค/๊ฐœ์ธํ‚ค or ๋น„๋ฐ€ํ‚ค๋ฅผ ํ†ตํ•ด ์„œ๋ช…๋˜๊ธฐ ๋•Œ๋ฌธ์—)
  • ๋ชจ๋ฐ”์ผ ์•ฑ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์ ํ•ฉํ•˜๋‹ค.
    ๋ชจ๋ฐ”์ผ ์•ฑ์€ ์—ฌ๋Ÿฌ ํ”Œ๋žซํผ ๋ฐ ๊ธฐ๊ธฐ์—์„œ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๊ณ , ์„œ๋กœ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์—์„œ ํ†ต์‹ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ด๋•Œ JWT๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”Œ๋žซํผ ๋…๋ฆฝ์ ์œผ๋กœ ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ ํ•ฉํ•˜๋‹ค.
  • ๋„คํŠธ์›Œํฌ ๋ถ€ํ•˜๊ฐ€ ์ ๋‹ค.
    httpํ—ค๋”๋‚˜ url ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ†ตํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์ „์†ก๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๐Ÿ“Œย ๋‹จ์ 

  • ํ† ํฐ์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ํŠธ๋ž˜ํ”ฝ์— ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ๋‹ค.
  • ํ† ํฐ์€ ๋ฐœ๊ธ‰๋˜๋ฉด ๋งŒ๋ฃŒ ๊ธฐ๊ฐ„ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ํ† ํฐ ๋งŒ๋ฃŒ ์ฒ˜๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

์ •๋ฆฌ

  • ์‚ฌ์šฉ ๋ชฉ์  : JWT ํ† ํฐ์€ ์‚ฌ์šฉ์ž ์ธ์ฆ๊ณผ ๋กœ๊ทธ์ธ ์œ ์ง€๋ฅผ ์œ„ํ•ด ์“ฐ์ธ๋‹ค
  • ํ† ํฐ์˜ ๊ตฌ์กฐ : Header, Payload, Signature
    • Header: ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜ (๊ณต๊ฐœํ‚ค/๊ฐœ์ธํ‚ค or ๋น„๋ฐ€ํ‚ค)
    • Payload : ํ† ํฐ ์ •๋ณด(๋Œ€์ƒ, ๋ฐœ๊ธ‰์‹œ๊ฐ, ๋งŒ๋ฃŒ์‹œ๊ฐ)
    • Signature : (Header+Payload) ์„œ๋ช… (์ธ์ฆ์šฉ)
  • ์žฅ๋‹จ์ 
    • ์žฅ์  : ๋„คํŠธ์›Œํฌ ๋ถ€ํ•˜๊ฐ€ ์ ๊ณ  ๋ชจ๋ฐ”์ผ ์•ฑ์— ์‚ฌ์šฉํ•˜๊ธฐ ์ ํ•ฉํ•˜๋‹ค

    • ๋‹จ์  : ํ† ํฐ ํฌ๊ธฐ๋ฅผ ์‹ ๊ฒฝ์จ์•ผํ•˜๊ณ , ๋งŒ๋ฃŒ ๊ธฐ๊ฐ„ ์ฒ˜๋ฆฌ๋ฅผ ๋”ฐ๋กœ ํ•ด์ค˜์•ผํ•œ๋‹ค


๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ๋Š” access token๊ณผ refresh token์— ๋Œ€ํ•ด ๋‹ค๋ฃจ๊ณ , ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•ด์•ผํ•˜๋Š”์ง€ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค! ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!๐Ÿ˜Ž


์ฐธ๊ณ ๋งํฌ

https://auth0.com/docs/secure/tokens/json-web-tokens
https://brunch.co.kr/@jinyoungchoi95/1
https://velog.io/@junghyeonsu/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%90%EC%84%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8%EC%9D%84-%EC%B2%98%EB%A6%AC%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95

profile
์ฆ๊ฑฐ์šด ๊ฐœ๋ฐœ์ž ๊น€๋ฏผ์ฃผ์ž…๋‹ˆ๋‹ค๐Ÿ™‚

0๊ฐœ์˜ ๋Œ“๊ธ€