class RegisterAPIView(GenericAPIView) :
serializer_class=RegisterSerializer
def post(self,request) :
serializers = self.serializer_class(data=request.data)
if serializers.is_valid() :
serializers.save()
return response.Response(serializers.data,status=status.HTTP_201_CREATED)
return response.Response(serializers.errors,status=status.HTTP_400_BAD_REQUEST)
사용자가 우리 프로그램에 json 데이터를 보낼 때 이를 파이썬 네이티브 객체로 바꾸는 역할을 한다.
왜냐하면 사용자가 JSON 데이터를 보낼 때 모델 객체처럼 매핑을 해야하기 때문
이것을 연결하는데 도움을 주는 것이 serializer이다.
또한 이를 python 객체를 json으로 변환하여 유저에게 제공한다.
class RegisterSerializer(serializers.ModelSerializer) :
password = serializers.CharField(max_length=128,min_length=6,write_only=True)
#password를 write_only로 설정하여, API 결과로는 보이지 않게 할 수 있다 .
class Meta() :
model=User
fields = ('username','email','password',)
def create(create,validated_data) :
return User.objects.create_user(**validated_data)
#토큰으로 인증된 유저 정보 가져오기
class AuthUserAPIView(GenericAPIView) :
permission_classes=(permissions.IsAuthenticated,)
def get(self,request) :
# print(request.user)
user = request.user
serializers=RegisterSerializer(user)
return response.Response({'user':serializers.data})
class LoginAPIView(GenericAPIView) :
authentication_classes=[]
serializer_class = LoginSerializer
def post(self,request) :
email = request.data.get('email',None)
password = request.data.get('password',None)
user = authenticate(username=email,password=password)
if user :
serializer = self.serializer_class(user)
return response.Response(serializer.data,status=status.HTTP_200_OK)
return response.Response({'message':"Invaild credentials,try again"},status=status.HTTP_401_UNAUTHORIZED)
from rest_framework.authentication import get_authorization_header,BaseAuthentication
from rest_framework import exceptions
import jwt
from django.conf import settings
from authentication.models import User
class JWTAuthentications(BaseAuthentication) :
def authenticate(self, request):
print(request.data)
#요청에서 header를 가져온다.
auth_header = get_authorization_header(request)
print(auth_header)
#받은 header를 utf-8로 디코딩한다.
auth_data = auth_header.decode('utf-8')
print(auth_data)
#token 형식이 Bearer + Token 이므로, ' '로 나눈다.
auth_token = auth_data.split(' ')
print(auth_token)
#토큰이 있는 리스트 길이가 2여야 하는데, 그렇지 않으면 유효하지 않은 토큰
if len(auth_token)!=2 :
raise exceptions.AuthenticationFailed('Token not valid')
#토큰만 취한다.
token=auth_token[1]
try:
#토큰과 SECRET_KEY, 발급시 사용한 알고리즘을 이용해서 디코딩한다.
payload=jwt.decode(token,settings.SECRET_KEY,algorithms='HS256')
print(payload)
#디코딩 결과로 얻은 username으로 유저 정보를 가져온다.
username=payload['username']
user=User.objects.get(username=username)
return (user,token)
#만료된 토큰일경우 예외처리
except jwt.ExpiredSignatureError as ex:
raise exceptions.AuthenticationFailed('Token is expired, login again')
#디코딩 에러일 경우 예외처리
except jwt.DecodeError as ex:
raise exceptions.AuthenticationFailed('Token is invalid')
#토큰 정보로 가져온 User가 존재하지 않을 경우 예외처리
except User.DoesNotExist as no_user:
raise exceptions.AuthenticationFailed(
'No Search user'
)
return super().authenticate(request)
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'authentication.jwt.JWTAuthentications',
]
}