import bcrypt
class 회원가입View :
def post(self,request) :
data = json.loads(request.body)
data_pw = data["password"]
#각종 유효성 검사....
#bcrypt로 암호화하여 DB에 저장
password_bcrypt = bcrypt.hashpw(bytes(data_pw,"utf-8"),bcrypt.gensalt())
Users.objects.create(
....
password =password_bcrypt,
)
이 작업을 하면서 암호화를 해야하는 당위성은 이해가 되었습니다.
(서버,DB가 털렸을 때 사용자의 개인정보/비밀번호가 털리면 큰 문제, 책임이 발생하므로 비밀번호는 암호화를 해야함)
그러나
1. 암호화라는게 어떻게 유출을 막는 것인지?
2. 왜 bcrypt 라는 모듈을 사용하는 것인지?
3. 다른 것과는 무슨 차이가 있는지?
등 암호화 자체에 대해 이해가 가지 않아 공부를 하게 되었습니다.
공부한 내용 전체를 적지 않고, 개요만 적습니다.
암호화가 양방향/단방향으로 나뉘고, 대칭키/ 비대칭키가 있고 그 세부 분류
양방향, 단방향, 대칭키, 비대칭키는은 어떻게 암호화가 이루어지는지에 대한 개요
->이를 통해, 왜 암호를 저장할 때 단방향(해시)암호화를 사용하는지 알게 되었습니다.
(암호화된 비밀번호를 복호화(평문으로 되돌리는것)을 할필요가 없음)
각 분류에 대해 각각 현재 사용되는 알고리즘
현재 사용되는 알고리즘의 세부 내용 (Bcrypt)
그런데 AES를 보려다보니... 디피-헬만 키교환, SSL/TLS, HTTPS에 대한 내용도 보게 되었습니다.
import jwt
def post(self, request):
data = json.loads(request.body)
data_email = data["email"]
jwt_token = self.make_jwt(data_email)
return JsonResponse({
"MESSAGE": "SUCCESS",
"access_token": jwt_token
}, status=200
)
def get(self, request):
if "Access-Token" in request.headers :
access_token = request.headers["Access-Token"]
if self.check_jwt(access_token) :
return HttpResponse("You are Logined!")
return HttpResponse("YOU ARE NOT Logined!")
로그인(인증) 기능을 구현하면서, access token을 헤더로 전달하고 헤더에서 데이터를 확인할 방법을 몰라 많이 헤맸습니다. jwt 공식문서에는 애초에 encode, decode에 대한 방법만 나와 있고, 이걸 응답에 포함하는 부분은 금방 작업했습니다.
그러나, 이 access token을 브라우저에 저장시키는 방법은 무엇인지? 또 access token을 다시 서버에서 input값으로 받으려면 어떻게 해야 하는지? 에 대한 설명이 전혀 없었습니다. (로그인 상태 유지)
현재 프론트엔드/HTML 부분을 아예 작업하지 않고 있습니다.
이에 따라 일단 브라우저에 저장시키는 방법은 넘어가고, (브라우저로 작업하지 않을 거니까)
form 형태로 post 하는 법 이외에 header에 데이터를 포함해 전달 받는 방법을 찾아야 했습니다.
데이터를 전달하는 방법을 찾기 전에, 대체 이 access token이 무엇인지 알아 봤습니다.
어렴풋이 알고 있던 쿠키가 이제 로그인 기능엔 사용되지 않는다는 점,
캐시/쿠키/세션/토큰의 차이에 대해 알게 되었습니다.
이에 따라 token이 주로 OAuth라는 데에 사용된다는 것도 알게 되어, OAuth에 대해 또 확인하고 넘어갔습니다. (생활코딩을 보니 실제로 구글계정에 대해 등록/인증 받는 법이 나와 있어서 다 봤음)
그러고 나니, OAuth에서 사용하는 Token이라는게, 3자간 통신에 사용하는 것이라,
제가 구현하고 있는 내용과는 다른 것을 깨달았습니다.
token을 헤더에 포함시켜서 request를 발생시키기 위해 HTTPie의 각종 메서드를 찾아 봤습니다. (기존에 회원가입 할 때부터 이미 사용하고 있었지만, 어렴풋이 쓰던 것만 쓰고 있었음)
이제 원하는 데이터를 원하는 위치에 집어넣을 수 있습니다.
좀 헤맨 부분이 있었는데, header에는 언더바( _ )가 들어가지 못하는데, 이를 몰라 시간을 좀 헤맸습니다.
사실상 실패한 부분입니다. 시간을 기준으로 유효성을 만들어야 했는데, shell에서 데이터를 하나하나 만들고 붙여넣기를 해야하는 작업이 너무 번거로워서 시간에 따라 유효성 검사를 하는 것은 완성하지 못했습니다.
일단 구현한 유효성 검사 방식은 다음과 같습니다.
그런데 이는 매번 ID/PW를 받는 것과 별로 차이가 없지 않나? 싶어 사실상 실패했다고 생각됩니다.
또, 토큰에 오류가 있어서 decode에 실패했을 때, 그리고 데이터의 id값이 DB에 존재하지 않을 때 발생하는 오류를 server status = 500이 아닌 다른 값으로 만드는 데까지는 실패했습니다. JWT 모듈에 대해 더 공부가 필요한 것으로 보입니다. (이후에 시간에 따른 유효성을 넣을 때 같이 첨부할 것)
이전까지는 Django에서 기본으로 제공하던 ID/PW 기능만 사용했었는데, 이를 직접 구현하려니 처음보는 내용이 많고 막막했습니다. 특히 암호화/알고리즘을 공부할 때는 "내가 어디까지 알아야하지?"라는 생각이 머리속에 끊이질 않았습니다.
다만 이런 암호화 알고리즘들을 직접 구현하거나 달달 외우지는 못하더라도, 개요 정도는 떠올릴 수 있는 상태가 되어, 어떤 과정으로, 어떤 input이 있으면 어떤 output이 나오는지 정도는 알게 된 것 같아 의미 있는 시간이었다고 생각합니다. (금방 까먹을 수 도 있겠지만!)
따지고 보면 10줄~20줄의 코드를 작성한 것 뿐인데 대체 뭐가 이렇게 찾아볼 내용이 많은지 ... 라는 기분도 있지만, 이번 한 번 뿐이고, 대신 다음에 비슷한 암호화/로그인 기능을 구현할 때에는 훨씬 빠르게 작업이 가능할 거라는 자신감이 생깁니다.
코드 한줄을 치더라도, "왜?" 라는 생각을 하며 작성하자는 생각이 있습니다. (지금은)
다만 지금처럼 공부하는 과정이 아니라 업무를 하게 되면 시간에 쫓기고, 결국 복사+붙여넣기를 하게 되지 않을까... 하는데 결국 어떤 방식으로 나가는것이 결과적으로 효율성이 높을지 생각만 많습니다.