๐Ÿ”ฅTIL#6. ์ธ์ฆ(Authentication) & ์ธ๊ฐ€(Authorization)

๋ฐฑ์Šน์ง„ยท2020๋…„ 11์›” 9์ผ
0

wecode Django ์‹ค์Šต

๋ชฉ๋ก ๋ณด๊ธฐ
8/16

What you will learn?

  1. ์ธ์ฆ๊ณผ ์ธ๊ฐ€์˜ ์ •์˜.
  2. ์•”ํ˜ธํ™” ๊ด€๋ จ ๊ธฐ์ˆ  ๋ฐ ์ด๋ก .
  3. ๋‹จ๋ฐฉํ–ฅ ํ•ด์‰ฌ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด bcrypt library ์‚ฌ์šฉํ•˜๊ธฐ.
  4. ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™” ๋Œ€์ƒ์„ ์œ„ํ•ด JWT(Json Web Token) ์‚ฌ์šฉํ•˜๊ธฐ.

1. ์ธ์ฆ๊ณผ ์ธ๊ฐ€์˜ ์ •์˜.

  1. ์ธ์ฆ(Authentication):
    ์œ ์ €์˜ identification๋ฅผ ํ™•์ธํ•˜๋Š” ๊ณผ์ •.
    account, password ์ •๋ณด๋ฅผ ๋ณด๋‚ด๋ฉด ์ด๋ฅผ ์„œ๋ฒ„์—์„œ ์ฒดํฌํ•˜๋Š” ์ ˆ์ฐจ๋ฅผ ํƒ€๋Š”๋ฐ ํ‰๋ฌธ์„ ์ด์šฉํ•˜๋ฉด ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ์œ ๋ฐœํ•˜๋ฏ€๋กœ ์•”ํ˜ธํ™” ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค.
  2. ์ธ๊ฐ€(Authorization):
    request ์ˆ˜์‹ ์‹œ ์ธ์ฆ๋œ ์œ ์ €์˜ ์š”์ฒญ์ธ์ง€๋ฅผ ํ™•์ธํ•˜๋Š” ์ ˆ์ฐจ.
    ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์€ ๋ฌผ๋ก  Netflix ๊ฐ™์€ ์„œ๋น„์Šค๋Š” ์ด์šฉ๊ฐ€๋Šฅ ๊ธฐ๊ฐ„ ๋“ฑ์˜ ์ •๋ณด๋„ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

2. ์•”ํ˜ธํ™” ๊ด€๋ จ ๊ธฐ์ˆ  ๋ฐ ์ด๋ก .

  1. ๋‹จ๋ฐฉํ–ฅ ํ•ด์‰ฌํ•จ์ˆ˜
    ์ค‘์š”ํ•œ ์ •๋ณด(password ๋˜๋Š” ๊ฐœ์ธ์‹ ์šฉ์ •๋ณด)์˜ ๊ฒฝ์šฐ ๋ณด์•ˆ์„ ์œ„ํ•ด ๋ณตํ˜ธํ™”๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•œ ์•”ํ˜ธํ™” algorithm์„ ์‚ฌ์šฉํ•œ๋‹ค. HS256์ด ๋Œ€ํ‘œ์ ์ด๋ฉฐ ์ด๋Ÿฐ algorithm์„ '๋‹จ๋ฐฉํ–ฅ ํ•ด์‰ฌํ•จ์ˆ˜ ์ฒ˜๋ฆฌ'๋ผ ๋ถ€๋ฅธ๋‹ค.
    ๋‹จ๋ฐฉํ–ฅ ํ•ด์‰ฌํ•จ์ˆ˜๋Š” ๋‹ค์Œ ์ทจ์•ฝ์ ์„ ๊ฐ–๋Š”๋‹ค.
    1. Rainbow table attack: ๋ฏธ๋ฆฌ ํ•ด์‰ฌ๊ฐ’๋“ค์„ ๊ณ„์‚ฐํ•ด ๋†“์€ ํ…Œ์ด๋ธ”.
      ํ•ด์‰ฌํ•จ์ˆ˜๋Š” ์›๋ž˜ ๋น ๋ฅธ ๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰๊ธฐ๋Šฅ์„ ์œ„ํ•ด ์„ค๊ณ„๋œ ๊ฒƒ์œผ๋กœ ์ด๋ฅผ ์ด์šฉ, ๊ณต๊ฒฉ์ž๋Š” ๋งค์šฐ ๋น ๋ฅธ ์†๋„๋กœ ์ž„์˜์˜ ๋ฌธ์ž์—ด์˜ ๋‹ค์ด์ œ์ŠคํŠธ์™€ ๋Œ€์ƒ ๋‹ค์ด์ œ์ŠคํŠธ๋ฅผ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ password๋ฅผ ์ถ”์ธกํ•˜๋ฉด ๊ธด์‹œ๊ฐ„์„ ๋“ค์ด์ง€ ์•Š๊ณ  ๊ณต๊ฒฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
      ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์•”ํ˜ธํ™”ํ•˜๋Š” ์ธก์—์„  salt, Key Stretching ๋“ฑ์˜ ๊ธฐ์ˆ ์„ ์ถ”๊ฐ€๋กœ ์ ์šฉํ•œ๋‹ค.
    2. Salt, Key Stretching
      • Salt : ์‹ค์ œ ๋น„๋ฐ€๋ฒˆํ˜ธ ์™ธ์— ๋žœ๋ค ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ Hash ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•.
      • Key Stretching : Salt ํฌํ•จํ•œ Hash๋ฅผ ๋‹ค์‹œ Hash ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•.
  1. ๋ณตํ˜ธํ™” ๊ฐ€๋Šฅํ•œ ์•”ํ˜ธํ™”
    ๋ณด์•ˆ์ ์œผ๋กœ ์ค‘์š”ํ•˜์ง€ ์•Š์€ ์ •๋ณด(๋ณด์•ˆ์ƒ ํƒˆ์ทจ๋˜๋„ ํฐ ์˜๋ฏธ๊ฐ€ ์—†๋Š” ๋ฐ์ดํ„ฐ)๋Š” ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™”์‹œ ์‚ฌ์šฉํ•˜๋Š” secret key๋งŒ ๋น„๊ณต๊ฐœ๋กœ ์ฒ˜๋ฆฌ, requester๊ฐ€ ์•”ํ˜ธํ™”๋œ ์ •๋ณด๋ฅผ ๋ณด๋‚ด๋ฉด responser๋Š” secret key ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฅผ ๋ณตํ˜ธํ™”ํ•˜์—ฌ ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
    Token์ด ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ login์„ ํ†ตํ•ด ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์—๊ฒŒ Service๋Š” ์•”ํ˜ธํ™”๋œ token์„ ๋ฐœ๊ธ‰ํ•˜๋ฉด ์‚ฌ์šฉ์ž ์ธก web client์˜ local storage๋‚˜ session ์— ์ €์žฅ, ์ด ํ›„ ์‚ฌ์šฉ์ž request์‹œ token์„ ํฌํ•จํ•˜๋ฉด Service๋Š” token์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์‚ฌ์šฉ์ž์˜ ์ธ๊ฐ€์ •๋ณด๋ฅผ ํ™•์ธํ•˜์—ฌ Service ์žฌ๊ณต์—ฌ๋ถ€๋ฅผ ์ œ์–ดํ•œ๋‹ค.

3. ๋‹จ๋ฐฉํ–ฅ ํ•ด์‰ฌ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด bcrypt library ์‚ฌ์šฉํ•˜๊ธฐ

  1. 'bcrypt' ํŒจํ‚ค์ง€๋ฅผ pip๋กœ ์„ค์น˜.
pip install bcrypt
  1. bcrypt ๋กœ Hash ์ฒ˜๋ฆฌ
import bcrypt

password = "1234"
salt     = bcrypt.getsalt()
print(salt)      # b'$2b$12$aj/EqXuq4/Dq83gaNlNHa.'

hashed_pw = bcrypt.hashpw(password.encode(), salt)
print(hashed_pw) # b'$2b$12$aj/EqXuq4/Dq83gaNlNHa.HMbvJHjp4F0T9c2ITj0Ez6sdiWwR/ai'

if bcrypt.checkpw(password.encode(), hashed_pw):
	return 'allowed password'
else:
	return 'non-allowed password'
  • hashpw() ํ˜ธ์ถœ์‹œ password๋Š” 'bytes' ํ˜•์‹์œผ๋กœ ์ž…๋ ฅ๋˜์•ผ ํ•œ๋‹ค. ์œ„์—์„  string ์ด๋ฏ€๋กœ encode() ๋ฅผ ํ†ตํ•ด bytes๋กœ ๋ณ€๊ฒฝ.
  • salt๊ฐ’์€ bcrypt.gensalt()๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด hashed๋œ pw ๋ฅผ ์–ป๋Š”๋‹ค.
  • checkpw() ๋ฅผ ํ†ตํ•ด hashed๋œ ์•”ํ˜ธ์™€ ํ‰๋ฌธ์„ ๋น„๊ต, ๋งค์นญ๋˜๋Š”์ง€๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.
    ๊ทธ๋Ÿฐ๋ฐ ์•”ํ˜ธํ™”์‹œ ์‚ฌ์šฉ๋œ salt ๋ฐ˜์˜์—ฌ๋ถ€๋ฅผ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ?
  • ์œ„์—์„œ salt์™€ hashed_pw ์ถœ๋ ฅ๊ฐ’์„ ๋น„๊ตํ•ด๋ณด๋ฉด salt๊ฐ’์ด hashed_pw์— '.'๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํฌํ•จ๋˜์–ด ์žˆ๋Š”๊ฒƒ์„ ์•Œ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ ์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ์•ˆ์— salt๊ฐ€ ์กด์žฌํ•˜๋ฏ€๋กœ checkpw ๊ณผ์ •์‹œ ๋น„๊ตํ•  ํ‰๋ฌธ๋งŒ ์žˆ์œผ๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค.

4. ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™” ๋Œ€์ƒ์„ ์œ„ํ•ด JWT(Json Web Token) ์‚ฌ์šฉํ•˜๊ธฐ.


1. 'pyjwt' ํŒจํ‚ค์ง€๋ฅผ pip๋กœ ์„ค์น˜

pip install pyjwt
  1. jwt๋กœ Token ๋งŒ๋“ค๊ธฐ
import jwt

# json ํ˜•์‹์˜ ์ •๋ณด๋ฅผ HS256 ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ SECRET_KEY ๋ฅผ ์ ์šฉํ•˜์—ฌ encoding
token = jwt.encode({'user_id':5}, SECRET_KEY, algorithm='HS256')

# token์ด ๋ฐœ๊ธ‰๋ ๋•Œ ์‚ฌ์šฉํ–ˆ๋˜ secret ํ‚ค์™€ algorithm ์œผ๋กœ decoding
decodeFromToken = jwt.decode(token, SECRET_KEY, algorithm='HS256')
  • JWT ๋กœ encode/decode ์‹œ secretํ‚ค์™€ algorithm์„ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค.
  • secret ํ‚ค์˜ ๊ฒฝ์šฐ ์™ธ๋ถ€๋กœ ๊ณต๊ฐœ๋˜๋ฉด ์•ˆ ๋œ๋‹ค. ํŠนํžˆ github๋กœ ๋ฒ„์ „ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น secret์€ git ๊ด€๋ฆฌ ๋Œ€์ƒ์—์„œ ์ œ์™ธํ•˜์—ฌ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
profile
12๋…„ .NET ๊ฐœ๋ฐœ ๊ฒฝ๋ ฅ์„ ๊ฐ€์ง„ ์›น ์ดˆ์งœ ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค :)

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