JWT을 통하여 회원가입 로그인 로그아웃을 토큰을 통하여 하는 방법을 알아내기 위해, 꽤 많은 구글링을 거쳤다. 공식문서에서는 simple-jwt를 사용하라고 했었는데, 해외 유튜버를 참고하여 pyJWT를 사용하여 구현하는 방법을 알아 낼 수 있었다. 이번 포스팅에서는 jwt 토큰을 주고받기 전에 password를 DB에 저장할때 암호화(hashing)을 통하여 저장 할 수 있는 방법에 대해서 기록하도록 하겠다.
## 필요한 라이브러리
Serializer을 사용해야하기 때문에 DRF를 pip를 통하여 설치해야 하며, setting.py에 restframework를 추가해주도록 하자
- Django-rest-framework
# serializer 작성
Serializer.py를 account 앱 또는 사용할 앱에다가 만들어 주도록 한다.
# 암호화 되지 않는 경우
# serializers.py
from rest_framework import serializers
from accounts.models import User
class UserSerializer(serializers.ModelSerializer) :
class Meta :
model = User
fields = '__all__'
# views.py
class RegisterView(APIView) :
def post(self, req):
serializer = UserSerializer(data=req.data)
serializer.is_valid(raise_exception=True)
# password didn't hashing
serializer.save()
return Response(serializer.data)
지금까지 위와같이 코드를 작성해 왔다. serializer에 원하는 모델을 등록해주고, view에서 serializer화하여 .save()메서드를 실행하면 알아서 해줬다. .save()메서드를 생각해 볼 필요가 있는데, 해당 데이터(여기에서는 User)가 존재한다면 .update()를 실행하게 해주고, 존재 하지 않다면 .create()를 자동으로 해준다. 아래 첨부한 사진처럼 돌아간다.
그냥 실행하면 어떤 결과를 낳는지 봐보도록 하자.
데이터베이스에서 해당 유저의 row값을 보게 되면 저렇게 보란듯이 password가 그대로 담겨있다. 이럴경우에는 당연히 보안에 치명적이지 않을까?
# 암호화 하기
from rest_framework import serializers
from accounts.models import User
class UserSerializer(serializers.ModelSerializer) :
class Meta :
model = User
fields = '__all__'
def create(self,validated_data):
password = validated_data.pop('password',None)
instance = self.Meta.model(**validated_data)
if password is not None :
#provide django, password will be hashing!
instance.set_password(password)
instance.save()
return instance
위에서 봤던거와 같이 우리가 작성한 view에서 .save()메서드를 호출하면 상황에 따라 create() 또는 update()가 호출된다고 했다. 그렇기 때문에 create()와 update()를 오버라이딩 해주면 된다는 것이다. 나는 새로생성한경우에만 해줄거였기 때문에 create()에 대해서만 작성해 줬다. password를 확인하고 .set_pawword() 메서드를 사용하면 알아서 딱 저장시켜준다!
class Meta :
# ...
# dose not return password in response json query
extra_kwargs = {
'password' : {'write_only' : True }
}
또 시리얼라이저에 해당코드를 넣어주게 된다면, response되는 데이터에서 password데이터는 오지 않는다. 참고하면 좋을거 같았다.
데이터베이스에 이렇게 저장이 된다!
# 비밀번호 확인하기
이제 의문이 들어야한다. 나는 그랬다. 그렇다면 프론트에서는 비밀번호를 날려줄텐데, 분명히 "password123" 이런식으로 사용자가 입력한 비밀번호 그대로를 보낼것이고, 서버는 그 데이터를 받아 데이터베이스에서 비교해야하는데 저렇게 암호화된 값이 온다면 그대로 비교해버리면 당연스럽게 일치하지 않을 것이다. 그에대한 해결로는
#view.py
class LoginView(APIView) :
def post(self,req):
email = req.data['email']
password = req.data['password']
user = User.objects.filter(email=email).first()
# is same?
if not user.check_password(password) :
raise AuthenticationFailed("Incorrect password!")
이렇게 장고에서 제공해주는 check_password를 사용하면 된다.
장고를 알아갈수록 재밌다. 다음 포스팅에서는 이번 포스팅을 기반으로 JWT 토큰으로 로그인 로그아웃 회원가입을 알아보도록 하겠다. 일단 위에 설명이 부정확할 수 있다. 왜냐하면 내가 참고한 유튜브와 장고 코드를 뜯어가면서 또 구글링하면서 얻은 정보들이기 때문이다. 공부해가면서 틀린 개념이었다면 수정하도록 하겠다. 그런것도 공부의 일환이라고 생각한다.
지금까지 얼추 공부하면서 view는 클래스기반(CBV)으로 사용하는것이 더 편하고 좋다는 생각이 들었고, 모델들의 쿼리셋과 serializer와 deserializer하는 방법에 대해서 확실히 알아가면 좋을거 같다는 생각이 들었다. 지금은 대강 개념만 아는 상태이고 사용할때마다 print찍어가면서 알아가는데, 뭔가 확실히 할 필요가 있다고 느꼈다. 아래에는 참고한 유튜브를 링크하도록 하겠다. 외국분이시다!
약 20분가량이 본 게시글과 관련 된 것이고, 그 이후는 JWT관련된 내용이다. 다음 포스팅에서 정리하도록 하겠다.
'• 개발 > Django' 카테고리의 다른 글
[Django] rest-framework에서 유저 프로필 이미지 등록, 유저 삭제시 파일 삭제, 커스텀유저 프로필 이미지 업로드, jwt (0) | 2022.02.21 |
---|---|
[Django] JWT#2, 장고 JWT토큰 사용하기, payload, Pyjwt, 장고 로그인 유지 (0) | 2022.02.19 |
[Django] 장고 커스텀 유저 만들기#2 forms.py admin.py , custom User, 장고 User 바꾸기 (0) | 2022.02.18 |
[Django] 장고 커스텀 유저 만들기#1 models.py , custom User, 장고 User 바꾸기 (0) | 2022.02.18 |
[Django] django-rest-framework 공식문서 튜토리얼 따라하기#5 (0) | 2022.02.16 |