AI 웹 개발 과정/개인 프로젝트

타임어택 07/08 - JWT 인증된 사용자만 접근 할 수 있는 View

만 기 2022. 8. 5. 16:49

 

Q1. 프로젝트에 jwt 인증을 사용해서 access token을 발급하도록 simple jwt 설정하기

- ACCESS_TOKEN_LIFETIME은 50분, REFRESH_TOKEN_LIFETIME은 1일로 설정

 

구현)

DRF JWT install

pip install djangorestframework-simplejwt

 

프로젝트 settings.py 추가

INSTALLED_APPS = [
	...
    'rest_framework_simplejwt',
]


# 토큰 유효시간 설정
from datetime import timedelta

SIMPLE_JWT = {
		# Access 토큰 유효 시간 설정하기
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=50),
		# Refresh 토큰 유효 시간 설정하기
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    ...

 

user/urls.py 추가

from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView

urlpatterns = [
	...
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

 

 

Q2. 지원자가 언제, 어떤 채용공고에 지원했는지 저장할 수 있도록 모델을 추가해보세요.

 

구현)

모델의 목적이 무엇인가? 

 ㄴ> 어떤 유저가 어떤 채용공고에 언제 지원했는지 알기 위해

필요한 필드가 뭘까?

 ㄴ> user, job_post, created_at

 

post/models.py 추가

class Apply(models.Model):
    user = models.ForeignKey(User, verbose_name='지원자', on_delete=models.CASCADE)
    job_post = models.ForeignKey(JobPost, verbose_name='채용공고', on_delete=models.CASCADE)
    created_at = models.DateTimeField('지원날짜', auto_now_add=True)

    def __str__(self):
        return f"{self.user.username}'s apply - {self.id}"

    class Meta:
        db_table = 'applies'

 

python manage.py makemigrations

python manage.py migrate

 

 

3. 2번에서 만든 모델의 객체를 직렬화 하기 위한 Serializer 구현

 

구현)

post/serializers.py 추가

class ApplySerializer(serializers.ModelSerializer):
    class Meta:
        model = Apply
        fields = ('user', 'job_post')
        # fields = '__all__'

 

 

4. 채용 공고에 지원하는 API 구현 

 - 지원하는 유저정보는 별도로 받지 않고 발급받은 access token 으로 인증할 것

 

구현) 

View 의 기능

* 인증받은 유저가 채용공고에 지원을 하면 해당 채용공고의 id와 현재 인증된 유저 id를 DB에 저장해야 한다.

* 인증된 유저가 아니면 요청이 불가하다.

 

post/urls.py

from .views import ApplyView

urlpatterns = [
	...
    path('apply', ApplyView.as_view()),
]

 

post/views.py

class ApplyView(APIView):

    authentication_classes = [JWTAuthentication]

    def post(self, request):
        user = request.user
        print(request.auth)

        if not request.auth:
            return Response({"message": "인증 실패"}, status=status.HTTP_401_UNAUTHORIZED)
        
        request.data['user'] = user.id
        apply_serializer = ApplySerializer(data=request.data)

        if apply_serializer.is_valid():
            apply_serializer.save()
            return Response({'message':'저장 완료'}, status=status.HTTP_200_OK)

        return Response(apply_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 

 

1. authentication_classes 로 인증 방식을 [JWTAuthentication] 으로 설정해준다.

(디폴트 값으로 프로젝트 settings.py 의 'DEFAULT_AUTHENTICATION_CLASSES' 에 'rest_framework_simplejwt.authentication.JWTAuthentication' 를 추가해주어도 된다.)

 

2. access token을 맞게 넣어줬다면 인증이 되어 request.user 에 인증된 유저가 들어오게 된다.

 

3. print(response.auth) 를 찍어보면 헤더에 넣었던 access 토큰 값이 나오는 것을 알 수 있다.

 

4. 이걸 이용해서 토큰이 없으면 401 에러와 에러메세지를 응답으로 준다.

 

* Authorization 에 토큰이 담겨있지 않을 때

 

* 토큰이 있지만 틀리거나 만료됐을 때