[210726 TIL] Django

Choi Rimยท2021๋…„ 7์›” 26์ผ
0

Django

๋ชฉ๋ก ๋ณด๊ธฐ
13/21
post-thumbnail

ํ•ด์‹œ (Hash)

>>> encoded_password = password.encode('utf-8')
>>> encoded_password
b'1234'
>>> type(encoded_password)
<class 'bytes'>
>>> type(password)
<class 'str'>
  • ์ธ์ฝ”๋”ฉํ•œ strํƒ€์ž…์€ bytes ํƒ€์ž…์œผ๋กœ ๋ฐ”๋€๋‹ค.
>>> decoded_password = encoded_password.decode('utf-8')
>>> decoded_password
'1234'
>>> type(decoded_password)
<class 'str'>
  • ๋””์ฝ”๋”ฉ๋œ bytes ํƒ€์ž…์€ ๋‹ค์‹œ str ํƒ€์ž…์œผ๋กœ ๋ฐ”๋€๋‹ค.
>>> hashed_password = bcrypt, hashpw( password, bcrypt.gensalt() )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'hashpw' is not defined
  • ์ธ์ฝ”๋”ฉ ๋˜์ง€ ์•Š์€ password๋ฅผ hashํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
>>> hashed_password = bcrypt.hashpw( password.encode('utf-8'), bcrypt.gensalt()  )
>>> hashed_password
b'$2b$12$JNrMFFk4GJxBlPhRlBgO1.KqxX7wUQtQNRNIXnrqtrk7FVUX/2h5K'
  • ์ธ์ฝ”๋”ฉํ•œ password๋ฅผ hash๋ผ๋ฉด ํŒจ์Šค์›Œ๋“œ๊ฐ€ ์ž˜ ํ•ด์‹œ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
>>> bcrypt.gensalt()
b'$2b$12$RIMTPk4mPJyb8so9ptXJlu'
>>> bcrypt.gensalt()
b'$2b$12$bzuGn3BE.kgH3nq5R6BJDO'
>>> bcrypt.gensalt()
b'$2b$12$1nwjw90b5ONVvUFWBuBTxu'
  • salt๊ฐ’์€ ๋žœ๋ค์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.
  • salt๊ฐ’์€ ๋žœ๋ค์œผ๋กœ ์ƒ์„ฑ๋˜๋Š”๋ฐ, ์–ด๋–ป๊ฒŒ hash๋œ ํŒจ์Šค์›Œ๋“œ๋“ค์„ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์„๊นŒ?
    • hash๋œ ํŒจ์Šค์›Œ๋“œ์—๋Š” salt ๊ฐ’์ด ์ถ”๊ฐ€๋˜์–ด ์žˆ๋‹ค.
>>> salt = bcrypt.gensalt()
>>> salt
b'$2b$12$KEi3lKW7D08IgUOUSpk/1O'
>>> hashed_password = bcrypt.hashpw( password.encode('utf-8'), salt
... )
>>> hashed_password
b'$2b$12$KEi3lKW7D08IgUOUSpk/1OyWyMgSzGTktOBaXTVFAq5o8Tvpc7zxm'
  • salt๊ฐ’์„ ๋ฏธ๋ฆฌ ์ €์žฅํ•ด๋‘๊ณ  hashed_password์— salt๊ฐ’์„ ์ง€์ •ํ•ด์ฃผ๋ฉด hashed_password ์•ˆ์— ์ง€์ •ํ•œ salt ๊ฐ’์ด ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
>>> type(hashed_password)
<class 'bytes'>
  • hash๋œ ํŒจ์Šค์›Œ๋“œ๊ฐ’์€ bytes ํƒ€์ž…์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— hash๋œ ํŒจ์Šค์›Œ๋“œ ๊ฐ’์„ decodeํ•˜์—ฌ ๋ฌธ์ž์—ด๋กœ ๋งŒ๋“ค๊ณ  ์ด ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค.

JWT

>>> encoded_jwt = jwt.encode( {'user-id': 5}, 'secret', algorithm='HS256' )
  • payload์—๋Š” ์ ˆ๋Œ€ ํŒจ์Šค์›Œ๋“œ๋‚˜ ์ด๋ฉ”์ผ ๋“ฑ ๊ฐœ์ธ ์ •๋ณด๋ฅผ ๋‹ด์•„์„œ๋Š” ์•ˆ๋œ๋‹ค.
  • ํ•˜์ง€๋งŒ user_id๋Š” ๋…ธ์ถœ๋˜์–ด๋„ ๋‹จ์ˆœํ•œ ์ˆซ์ž์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผ ๊ถŒํ•œ์ด ์—†๋Š” ํ•œ ์˜๋ฏธ์—†๋Š” ๋ฐ์ดํ„ฐ์ด๋‹ค.
>>> encoded_jwt
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyLWlkIjo1fQ.tBQu0HfnOYK7lL3tH5ImgsI-y4Jz1RKscJWbV3U2QMI'
>>> encoded_jwt
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyLWlkIjo1fQ.tBQu0HfnOYK7lL3tH5ImgsI-y4Jz1RKscJWbV3U2QMI'
>>> type(encoded_jwt)
<class 'str'>
  • token์˜ ํƒ€์ž…์„ ํ™•์ธํ•˜๋ฉด str ํƒ€์ž…์ธ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์—ฌ๊ธฐ์„œ ๋‹ค๋ฅธ ๋ถ„๋“ค์€ bytes ํƒ€์ž…์ด ๋‚˜์™€์„œ ์™œ ๋‚˜๋Š” str ํƒ€์ž…์œผ๋กœ ๋‚˜์˜ค๋‚˜ ํ™•์ธํ•ด ๋ดค๋”๋‹ˆ PyJWT ๋ฒ„์ „ v2.0.0 ์ด์ƒ์ด๋ผ๋ฉด jwt.encode์˜ ๋ฐ˜ํ™˜๊ฐ’์ด bytes ํƒ€์ž…์ด ์•„๋‹ˆ๋ผ string ํƒ€์ž…์ด๋ผ๊ณ  ํ•œ๋‹ค.

bcrypt

  • bcrypt๋Š” str ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ Bytes ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”ํ•œ๋‹ค.
    • ๋”ฐ๋ผ์„œ ์•”ํ˜ธํ™”์‹œ์— bytesํ™” ํ•ด์•ผ ํ•œ๋‹ค.
  • ํŒŒ์ด์ฌ์—์„œ๋Š” str์„ encodeํ•˜๋ฉด bytes(์ด์ง„ํ™”)๊ฐ€ ๋˜๊ณ , bytes๋ฅผ decodeํ•˜๋ฉด strํ™” ํ•œ๋‹ค.
  • encode, decode ์‹œ์— ์šฐ๋ฆฌ๊ฐ€ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด 'UTF-8' ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž ๊ทœ๊ฒฉ์„ ์‚ฌ์šฉํ•œ๋‹ค.

ํšŒ์›๊ฐ€์ž… ์‹œ ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”ํ•ด์„œ ์ €์žฅ

hashed_password = bcrypt.hashpw(
        data['password'].encode('utf-8'),bcrypt.gensalt()
        ).decode()
      
      User.objects.create(
        name       = data['name'],
        email      = data['email'],
        password   = hashed_password,
        mobile     = data['mobile'],
        address    = data['address'],
        birth_date = data['birth_date']
        )

password๋ฅผ DB์— ์ฒ˜์Œ ์ž…๋ ฅํ•  ๋•Œ decode() ํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š”?
bcrypt.hashpw('1234'.encode('utf-8'),bcrypt.gensalt()) ๋Š” b'$2b$12$8EPF0NBZotiz0aPDVKwQHumq6dMhMnfP1BwC3xh2lKigedKeH4ucq'
์ธ๋ฐ,
bcrypt.hashpw('1234'.encode('utf-8'),bcrypt.gensalt()).decode()๋Š”
'$2b$12$8EPF0NBZotiz0aPDVKwQHumq6dMhMnfP1BwC3xh2lKigedKeH4ucq'
๋กœ ์•ž์˜ ๋ฐ”์ดํŠธ๋ผ๋Š” ํ‘œ์‹œ๋ฅผ ๋นผ์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค

  • ์ž…๋ ฅํ•œ password๋Š” str ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์— encode๋ฅผ ์ด์šฉํ•ด bytes ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
  • ์ด ๋•Œ bytes ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•œ password ์•ž์—๋Š” b๊ฐ€ ๋ถ™๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์‹œ decode๋ฅผ ํ•ด์ฃผ์–ด ๋งจ ์•ž์˜ b๋ฅผ ์‚ญ์ œํ•ด์ค€๋‹ค.

๋กœ๊ทธ์ธ ์‹œ ๋น„๋ฐ€๋ฒˆํ˜ธ์˜ ์ผ์น˜์—ฌ๋ถ€ ํ™•์ธ

>>> bcrypt.checkpw(new_password.encode('utf-8'), hashed_password)
True
  • bcrypt.checkpw() ๋ฉ”์†Œ๋“œ๊ฐ€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•˜๋Š” ์ž‘์—…์„ ํ•œ๋‹ค.
  • ๋ฉ”์†Œ๋“œ ๊ทœ์น™
    • ์ž…๋ ฅ๋ฐ›์€ ํŒจ์Šค์›Œ๋“œ, ์ €์žฅ๋œ ์•”ํ˜ธํ™”๋œ ํŒจ์Šค์›Œ๋“œ
    • ์ž…๋ ฅ๋ฐ›์€ ํŒจ์Šค์›Œ๋“œ์™€ ์ €์žฅ๋œ ์•”ํ˜ธํ™”๋œ ํŒจ์Šค์›Œ๋“œ๋ฅผ ๋น„๊ตํ•œ๋‹ค.
    • ๋‘˜๋‹ค ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ bytes ์—ฌ์•ผ ํ•œ๋‹ค.
user_info = User.objects.get(email=data['email'])

        input_pw = data['password']

        user_pw = user_info.password

        if not bcrypt.checkpw(input_pw.encode('utf-8'), user_pw.encode('utf-8')):
          return JsonResponse({'message':'INVALID_USER'}, status=401) 

        return JsonResponse({'message':'SUCCESS'}, status=200)
  • input_pw์™€ user_pw ๋‘˜ ๋‹ค ํ˜„์žฌ str ํƒ€์ž…์ด๊ธฐ๋•Œ๋ฌธ์— encode๋ฅผ ํ†ตํ•ด bytes ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด ๋น„๊ตํ•ด์ค€๋‹ค.

๋กœ๊ทธ์ธ ์™„๋ฃŒ ํ›„ ์—‘์„ธ์Šค ํ† ํฐ

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ

  • ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ž€ ํŠน์ • ํ•จ์ˆ˜์˜ ๋ฐ”๋กœ ์œ„์— ๋ถ™์–ด์„œ ํŠน์ • ํ•จ์ˆ˜ ์‹คํ–‰ ์ „ ๋จผ์ € ์‹คํ–‰ ๋˜์–ด ์‚ฌ์ „์— ํ•˜๊ณ  ์‹ถ์€ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.
  • ์ƒ์„ฑํ•  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ
    • ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ์‚ฌ์šฉ์ž๊ฐ€ ๊ทธ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•  ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ์‚ดํŽด๋ณด๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ
    • ํ† ํฐ์œผ๋กœ ๊ถŒํ•œ์ด ํ™•์ธ๋˜์ง€ ์•Š์œผ๋ฉด ํŠน์ • ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ ํ•จ์ˆ˜๋Š” ์‹คํ–‰๋˜์ง€ ์•Š์Œ

๊ฒŒ์‹œ๋ฌผ ๋“ฑ๋ก ๊ธฐ๋Šฅ ๊ตฌํ˜„

Posting app

  • djando app ์—์„œ๋Š” ์ฃผ๋กœ ๋‹ค๋ฃจ๋Š” ๋ฐ์ดํ„ฐ์˜ ์ข…๋ฅ˜๊ฐ€ ๋‹ฌ๋ผ์ง€๋Š” ์‹œ์ ์—์„œ ์•ฑ์„ ๋ถ„๋ฆฌํ•œ๋‹ค.
  • ๊ฒŒ์‹œ๋ฌผ์€ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ์™€๋Š” ๊ทธ ์„ฑ์งˆ์ด ๋‹ฌ๋ผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ํ…Œ์ด๋ธ”์„ ๋”ฐ๋ผ ๊ด€๋ฆฌํ•œ๋‹ค.
  • ์ฃผ๋กœ ๋‹ค๋ฃจ๋Š” ํ…Œ์ด๋ธ”์ด ๋‹ฌ๋ผ์ง€๋ฉด ์•ฑ์„ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

Posting Model ์ƒ์„ฑ

  • ๊ฒŒ์‹œ๋ฌผ์„ ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์‚ฌ์šฉ์ž, ์ƒ์„ฑ ์‹œ๊ฐ„, ์ด๋ฏธ์ง€ url์ด ํ•„์š”ํ•˜๋‹ค.
  • ํ•ด๋‹น ๊ฒŒ์‹œ๋ฌผ์˜ ์œ ์ €๋Š” Foreign Key๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด๋ฏธ ์„œ๋น„์Šค์— ๊ฐ€์ž…๋œ ์‚ฌ๋žŒ์œผ๋กœ ์—ฐ๊ฒฐํ•œ๋‹ค.

<์ฐธ๊ณ >

profile
https://rimi0108.github.io/

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