Django Instagram - Auths

jinatra·2021년 8월 26일
0

Django

목록 보기
6/9
post-thumbnail

Django Instagram - Auths


앞선 글에서 Authentication(인증)과 Autorization(인가), 그리고 Bcrypt와 JWT에 대해서 다루었다.

이제 내가 만든 인스타그램에 어떻게 작동하는지 적용시켜볼 것이다.


Bcrypt

비밀번호 암호화에 쓰이는 라이브러리인 Bcrypt이다.
우선 사용하고자 하는 가상환경에 Bcrypt를 아래와 같이 설치

pip install bcrypt

이제 views.py의 SignUpView에 import하여 비밀번호를 암호화시켜보자.

기존의 SignUpView에 추가된게 있다면, 이메일 중복 확인 단계-객체 생성 단계 사이에 비밀번호 암호화 단계를 추가해줬다.

  1. salting을 위한 bcrypt.gensalt()salt라는 변수 안에 담기 (그냥 다시 쓰기 귀찮아서 ㅎㅎ)
  2. 비밀번호 암호화를 위해 bcrypt.hashpw()를 사용
    2-1. hashpw() 함수 안엔 암호화를 시킬 데이터를 byte타입으로 넣어주고, 두번째 파라미터엔 salt를 넣어준다.
  3. DB에 들어갈 때에는 str 타입으로 들어가야하므로 다시 decode시킨 값을 decoded_password라는 변수로 선언
  4. 생성될 User 객체의 비밀번호(password)를 decoded_password로 변경

암호화된 비밀번호를 다시 str타입으로 디코드하는 이유

byte타입 데이터가 DB에 담길때에는, b'data' 와 같이 b''가 추가가 된다.
이를 나중에 불러올 때에는 저 b'' 자체를 str으로 인식하는 오류가 생길 수 있어 다시 decode 시켜주는 것이다.


비밀번호 암호화 확인

이제 정상적으로 유저가 생성됐는지 확인해보자.

유저는 잘 생성됐고, DB에는 어떻게 담겼나 보면..

암호화시킨 비밀번호 ruletheworld12@가 암호화되어 DB에 저장된 것을 확인할 수 있다.

(만약 str타입으로 decode 하지 않았다면 mySQL DB에는 b'$2b$12$QqOqUR7RuPtMQtzZqQc13OEsiUkxHbIE6IUS97EdQK1WAO.WRtpym'와 같이 저장되었을 것이다.)


로그인 확인 (암호화된 비밀번호)

이제 DB에는 암호화된 비밀번호로 적용이 됐다.
하지만 사용자는 로그인 화면에서 비밀번호를 칠 때 원래 비밀번호를 칠 것이다.
그럼 기존에 하던 것처럼 DB와 비교할 수 없을텐데 어떻게 할까?

바로 Bcrypt의 checkpw()함수가 그걸 도와준다.
이걸 이용해서 아래와 같이 코드를 짜보았다.

sign_in_password와, email 일치를 통해 가져온 유저 객체의 password와 비교해서 일치하는 지를 checkpw()함수를 통해 확인하면 된다.

확인해보자.

뭔가가 잘못돼있는거 같다.
로그를 확인해보자.

bcrypt 함수 안에는 인코드된 byte 타입 데이터가 들어가야 하는데 내가 깜빡하고 str 타입인채로 넣었다..!

그래서 두 파라미터를 다시 byte 타입으로 인코드하였다.

이제 다시 로그인해보자.

잘 된다!

혹시나 해서 이메일도 틀리게 해보고, 비밀번호도 틀리게 해보고, KeyError도 실험해봤는데 정상적으로 잘 떴다.


JWT

이제 로그인이 성공되었을 때, JWT를 이용하여 토큰을 생성하는 과정을 복습해볼 것이다.

JWT를 import 한 후 encode() 함수를 이용해서 토큰을 생성하면 된다.

먼저 가상환경에서 JWT를 설치해주자.

pip install pyjwt

이후 기존에 작성한 SignInView의 코드를 아래와 같이 편집했다.

  • 비밀번호 확인이 완료됐다면 토큰을 생성
  • token이라는 변수에 jwt.encode() 함수를 사용
  • parameter로 들어갈 데이터는 payload와 SECRET_KEY, 그리고 algorithm이다.
  • SECRET_KEY 는 우리가 별도로 my_settings.py에 옮겨두었으므로 해당 데이터를 import

일반적으로 토큰을 발급하는 위치는 보안에 안전한 DB의 id로 지정을 해주어야 한다. (이메일, 이름 등은 개인정보이므로!!)

토큰은 head에 담겨져 FE에게 보내질 것이다.


토큰 생성 확인

토큰이 정상적으로 생성 및 출력되었다!!


리팩토링(?)

좋아하지 말고 코드를 한번 더 봐보자.
우리는 user 객체를 가져오기 위해서 get 메소드를 쓴 동일한 절차를 두번 거치게 하고 있다.
이러면 아마 처리 속도가 더 길어질것 같다.

그러니 user 라는 하나의 변수 안에 담는 형태로 해서 아래랑 같이 바꿔봤다.

다시 로그인과 토큰 발급이 잘 되나 볼까

아주 만족스럽다.


리팩토링이 맞는지는 모르겠는데, 아무튼 위키에서 아래와 같이 설명하고 있으니 맞지 않을까 싶다.

리팩터링(refactoring)은 소프트웨어 공학에서 '결과의 변경 없이 코드의 구조를 재조정함'을 뜻한다. 주로 가독성을 높이고 유지보수를 편하게 한다.




Take Away

목표 완성

내가 목표로 하고자 하는 곳까지는 스스로의 힘으로 도달하였다.
이제 여기서 더 나아가 조금 더 복잡한 모델(FK, M2M emd)들이 적용된 app도 생성해봐야 겠다.


리팩토링

내가 한게 리팩토링이 맞는지는 모르겠는데, 아무튼 위키에서 아래와 같이 설명하고 있으니 맞지 않을까 싶다.
코드의 가독성과, 데이터 처리 속도를 생각하며 짠거니 만족하고 싶다.

"리팩터링(refactoring)은 소프트웨어 공학에서 '결과의 변경 없이 코드의 구조를 재조정함'을 뜻한다. 주로 가독성을 높이고 유지보수를 편하게 한다."





참고
https://ko.wikipedia.org/wiki/리팩터링

profile
으악

0개의 댓글