이 글은 길어질 예정이다.
로그인 그리고 js와의 통신은 결코 쉽지 않았다.
수많은, 정말 수많은 오류를 만났지만 오류를 해결하는 데 급급해 기록을 남기지 못해 아쉬울 따름이다.
다만 해결된 지금 나와 똑같은 오류를 마주했을 사람들에게 해결법을 남기고자 한다.


먼저 통신의 과정을 설명한다. 통신은 다양한 용도로 사용했지만 그 중 한가지만 예시로 첨부하는 바이다.

axios
      .post("http://localhost:8000/make_prompt/", data)
      .then((response) => {
        console.log(response);
        navigate("../result"); // POST 요청 완료 후에 navigate 호출
      })
      .catch((error) => {
        console.log(error);
      });

js(front)파일에서 axios통신을 요청한다. axios통신은 js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리이다. 쉽게 말하면 js에서 서버와 통신하고자 할 때 사용되는 라이브러리이며 http프로토콜을 사용하는 것이다.

axios통신을 위해서는 설치도 필요하다.

import axios from "axios";

axios 통신을 통해 request를 요청하고자 하는 back-end의 링크를 작성해 준다. 이 프로젝트의 경우 포트 8000번이 back-end의 주소이며 /make_prompt/는 우리가 생성한 url이다.

💡 포트 번호에 유의해야 한다. 여기서도 js파일이 실행되는 포트는 3000번이나 요청 주소가 8000번 포트이므로 주소에 8000포트를 적어주어야 한다. 내 주소가 아닌 요청 주소를 적는다는 것을 헷갈리지 말자.

GET방식은 보안에 취약하고 우리는 추후 이 서비스 배포 예정에 있기 때문에 POST방식으로 요청하였으며,전달하고자 하는 데이터를 url링크 옆에 적어준다.
(데이터는 model로 정의해 두면 좋다.)

✨모든 통신에서 예외 처리는 필수이다.


js에서의 처리(요청)이 끝났다면 이제 응답하는 부분을 구현할 차례이다.

def post(self, request, *args, **kwargs):
        place = request.data.get('place')
        companions = request.data.get('companions')
        nights = request.data.get('nights')
        theme = request.data.get('theme')

        # 여기서 가져온 데이터로 하고 싶은 작업을 진행합니다.
        #(예시)
        #userPlan = Userplan(place=place, companions=companions, nights=nights, theme=theme)
        #userPlan.save()
        

        
        return Response()

js와의 통신을 통해 front에서 받아온 변수를 사용하고 싶은 class내부에 post함수를 구현하였다. 인자는 순서대로 그 class의 인스턴스, 요청 객체, 반응형(개수가 정해지지 않은)인자, 넘기는 인자 키워드 튜플 인데 알아두면 좋다.

함수 내부에서는 드디어 전달된 데이터 중 특정 필드를 지정해 그 값을 가져온다.

변수명 = request.data.get('필드명')

그리고 나면 받아온 데이터를 마음껏 사용하고,
return response()로 응답을 돌려주면 끝이 난다.


로그인도 id와 password를 전달하는 것은 같은 통신 방식으로 할 수 있다. 그러나 나는 사용자를 비교하지 못하는 오류에 봉착했다.

결과적으로는 jwt인증을 하지 않아서 발생한 문제였다.
추가적으로 jwt인증 방법을 소개하겠다.

먼저 jwt를 설치한다.

pip install djangorestframework djangorestframework-jwt

다음으로는 settings.py에 가서 REST_FRAMEWORK부분에 아래와 같이 추가한다.

	'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication'
    ]

이것도 추가한다.

JWT_AUTH = {
    'JWT_ALLOW_REFRESH' : True
    'JWT_SECRET_KEY' : SECRET_KEY,
    'JWT_ALGORITHM' : 'HS256',
    'JWT_EXPIRATION_DELTA' : datetime.timedelta(days=1),
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7)
}

jwt토큰은 유효 기간이 정해져 있어 자동으로 갱신 받기 위해 allow_refresh를 true로 설정한다. 해시(암호화)알고리즘은 HS256을 사용했다. JWT_EXPIRATION_DELTA는 토큰을 갱신할 수 있는 기간을 의미한다. 즉, 로그인이 유지되는 시간이다.

➕secret key는 django의 보안 요소로서 분리한 후 settings파일에서 다시 받아오는 것이 좋다.

def get_secret(setting, secrets=secrets):
    """비밀 변수를 가져오거나 명시적 예외를 반환한다."""
    try:
        return secrets[setting]
    except KeyError:
        error_msg = "Set the {} environment variable".format(setting)
        raise ImproperlyConfigured(error_msg)

SECRET_KEY = get_secret("SECRET_KEY")

이제 urls.py에서도 아래 링크를 추가한다.

	path('api/token/', obtain_jwt_token)
    path('api/token/refresh/', refresh_jwt_token), 
    path('api/token/verify/', verify_jwt_token),

마지막으로..........
views.py파일에

from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

를 추가하고, 로그인 데이터(id,pwd)를 통신하는 함수 앞에 아래 코드를 한번 더 추가한다.

@api_view(['GET'])
@permission_classes((IsAuthenticated, ))
@authentication_classes((JSONWebTokenAuthentication,))

이로서 jwt토큰 인증 방식은 끝이다.

엄청 길고 복잡하며, 추가로 설정할 수 있는 것들도 많지만 최소한만을 설명했다.


통신은 axios방식만 존재하지는 않는다. 유명한 통신 방식으로는 json도 있다. 그러나 나는 가장 쉬운 방식을 택했으며, 상황에 맞게 사용하면 된다.

통신 방식을 소개했지만 실제로 이 통신을 시도하다 보면 이론과는 다른 오류들을 다양하게 만날 수 있다.(jwt는 더더더 그렇다.) settings에 포함되어야 할 내용이 빠질 수도 있고, 그냥 네트워크 오류일 수도 있고, 서버가 꺼져 있는 상태에서 재시도해 오류 없이도 실행되지 않을 수 있다.
당황하지 말고 이런 가능성들을 순서대로 체크해 오류를 해결해 나가면 문제는 해결되고, 첫 통신에 성공하면 그 뒤로는 통신을 자유롭게 사용할 수 있다.💦

profile
호기심으로 시작해, 논리적으로 개발하는, 백엔드 개발자 임지희 입니다. 소개에 있는 포트폴리오 및 github에서 프로젝트 상세내용과 코드를 보실 수 있습니다:)

0개의 댓글