지난 시리즈에서 비밀번호 생성, 저장, 로그인시 입력한 비밀번호 일치여부 확인 후 토큰발행, JsonResponse body에 담아서 전달하는 과정까지 진행했다.
프론트엔드에서는 로그인해서 받은 토큰을 가지고 유저가 활동할 수 있도록 토큰을 http header 에 넣어 계속 보내주게 된다. 백엔드에서는 유저 인증이 필요한 기능을 수행하는 함수가 있다면, 로그인 한 유저인지를 확인하는 과정을 거쳐야 한다.
즉, 로그인이 필요한 다양한 함수(활동) 실행 전, 토큰을 확인하는 함수를 데코레이터로 실행하면 된다.
로그인 이후 구매, 찜하기, 회원정보 수정하기 등 로그인 이후 실행되는 함수가 다양한 App 에 존재하므로, manage.py 와 같은 디렉토리에 utils.py
라는 파일을 만들어 내부에 데코레이터를 작성하고, App 의 views.py 에서 해당 데코레이터를 import 해 줄 것이다.
우선 코드를 보자.
- line 6 : 함수를 인자로 받는다.
- line 21 : 내부의 함수를 실행시킨다.
- line 7 : 내부의 함수. http 의 request를 인자로 받는다.
- line 8-10 : request.header 에 {'Authorization': 암호화된 토큰} 처럼 키값으로 'Authorization' 이 오지 않으면 에러를 반환한다.
이 키값은 토큰 발행 시 키값과 동일. 키가 알맞게 온 경우, 해당 토큰은 token 이라는 변수에 할당.
- line 12-13 : token 은 str 형식으로 전달되고, 이를 바로 디코딩 함수에 넣어준다. jwt의 decode method는 decode('utf-8')과는 다른 것으로, 암호화된 토큰을 해석한다는 의미의 decode 이다. 따라서 method 의 인자는 스트링 형식의 암호화된 토큰, 토큰을 암호화 할 때 사용했 던 시크릿 키와 알고리즘이다.
- line 14 : 로그인 기능을 수행하는 함수에서 토큰 값으로 유저의 아이디를 넣어줬다. decoded_token 의 키값을 로그인 시 사용한 키와 일치시키고, 값(id)을 객체인 request 의 속성으로 넣어주었다. request 는 request.header, request.body, request.account_id 처럼 해석한 토큰의 값을 속성으로 가지게 된다.
- line 16-17 : 토큰이 오긴 왔는데, 해석이 불가능 한 경우(나의 경우는 기존 토큰을 일부 수정해서 넣어보았다.) DecodeError 가 나게된다. 이 에러를 try-except 문으로 잡아준다.
- line 19 : 인자로 받았던 함수를 실행시킨다. 인자의 request 는 이제 account_id 라는 속성을 가지는 request 가 되었다.
위의 데코레이터를 적용한 실제 기능을 하는 함수이다. 로그인 한 유저의 wishlist 를 추가/삭제하는 기능을 구현하였다.
account.views.py
- line 115 : utils.py 의 login_required 함수를 데코레이터로 적용시켜 줌
- line 116 : request 를 인자로 받으며, request 는 account_id 라는 속성을 가짐
- line 124 : Wishlist 모델은 account / product 를 FK로 받는데, account_id 는 request.account_id 로 확인할 수 있음.
모델을 짜다가 짝꿍과 생각한 것인데, 리뷰작성하는 함수를 구현할 때, 유저가 이미 구매 완료하고 리뷰를 작성하지 않은 상품인지 여부를 확인하는 부분을 똑같이 데코레이터로 짜도 될 것 같다. 다음주 후반쯤 구현해보고싶다.