로그인 기능
Logic
- request.body를 통해 로그인 정보(email, password)를 전달 받는다.
- 먼저 email이 데이터베이스에 존재하는지 확인하여 존재하지 않는다면 사용자가 존재하지 않는다는 에러 메시지를 전달하며 응답한다.
- 만약 존재한다면, user 인스턴스와 request.body 정보를 활용하여 LoginSerializer를 생성한다.
- 유효성 검사를 마친 뒤, access token을 담아 응답한다.
DRF - Simple JWT
user = User.objects.get(id=obj.id)
refresh = RefreshToken.for_user(user)
return str(refresh.access_token)
- JWT(Json Web Token)을 활용하기 위해 djangorestframework simple jwt를 설치하여 사용하였다.
- 이를 활용하면 유저 인스턴스를 활용해 쉽게 토큰을 생성하고 유효기간을 설정하는 등 토큰 관리를 유용하게 해준다.
SerializerMethodField 활용하기
class LoginSerializer(serializers.ModelSerializer):
access_token = serializers.SerializerMethodField()
def get_access_token(self, obj):
user = User.objects.get(id=obj.id)
refresh = RefreshToken.for_user(user)
return str(refresh.access_token)
- access token을 발급 받고, serializer에 추가하는 방법을 찾던 와중에
SerializerMethodField
를 알게 되었다.
- 원하는 필드를 커스텀할 수 있는 필드이고, get_(field name)로 함수를 설정하면 그 값을 설정할 수 있다.
Total Codes 🗂
class Login(APIView):
def post(self, request):
try:
user = User.objects.get(email=request.data['email'])
serializer = LoginSerializer(user, data=request.data, partial=True)
if serializer.is_valid(raise_exception=True):
return Response(data=serializer.data, status=400)
return Response(data='INVALID_LOGIN_INFO', status=400)
except User.DoesNotExist:
return Response(data='사용자가 존재하지 않습니다.', status=400)
class LoginSerializer(serializers.ModelSerializer):
access_token = serializers.SerializerMethodField()
class Meta:
model = User
fields = ('id', 'email', 'password', 'access_token')
extra_kwargs = {
'password': {'write_only': True},
'email': {'write_only': True}
}
def validate_password(self, obj):
email = self.initial_data['email']
password = User.objects.get(email=email).password
if check_password(obj, password):
return password
raise serializers.ValidationError('비밀번호가 올바르지 않습니다.')
def get_access_token(self, obj):
user = User.objects.get(id=obj.id)
refresh = RefreshToken.for_user(user)
return str(refresh.access_token)