로그인 token 체크

BackEnd_Ash.log·2020년 2월 16일
1

앞서 api 를 작성했을때 ,
login 을 하게 되면 토큰을 발행하는것을 했다.
토큰을 발행하게 되면 서버에 저장하지 않아 부하가 적어진다.
그런데 서버에 저장하지않게 된다면 ... 어떻게 사용자가 맞는지 확인을 할 수가 있을까 ??
바로 토큰에 secret_key 가 있는데 그것으로 확인을 한다.
어떠한 상품을 구매한다거나 댓글을 쓴다거나 게시판작성 등등을 한다거나
사용자의 인증이 필요한 로직이 들어갈때는 사용자인지 아닌지 확인이 필요하게 된다.

토큰을 발행하고 프론트엔드는 토큰을 받은후에 header 에 저장하게 된다.
그리고 새로운 요청이 올때마다 HTTP request header 에 넣어서 보내주면 로그인된 상태로 유지시켜준다.
프론트엔드가 백엔드로 토큰을 header 로 보내주게 되면 우리도 header 로 그 토큰을 받아야한다.

토큰을 체크하면 인증체크가 여러번 들어가게 되니
따로 함수로 빼버려서 데코레이터로 해버리면 된다.

데코레이터 ??가 뭐지 ??

데코레이터는 함수가 실행되기전에 위에 장식을 한다는것인데 ,
그 함수가 실행되기 전에 먼저 실행이 된다.

https://velog.io/@ash3767/decorator

token check decorator


import json, jwt
from django.http import JsonResponse
from .models import Account

def login_decorator(func):
    def wrapper(self, request, *args, **kwargs):
        try:
            auth_token = request.headers.get('Authorization', None)
            print('auth_token', auth_token)
            # auth_token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6Impha2R1QGdtYWlsLmNvbSJ9.s0Io_fAFvz-_8oaVuJrWiFyVUnFzxmk_YQncU5QId3Y
            payload = jwt.decode(auth_token, 'wecode', algorithm='HS256')
            print('payload', payload)  # payload {'email': 'jakdu@gmail.com'} <class 'dict'>
            request.user = Account.objects.get(email=payload["email"])
            return func(self, request, *args, **kwargs)

        except Account.DoesNotExist:
            return JsonResponse({'message': 'INVALID_USER'}, status=400)
        except TypeError:
            return JsonResponse({'message': 'INVALID_VALUE'}, status=400)
        except KeyError:
            return JsonResponse({'message': 'INVALID'}, status=400)

    return wrapper
  1. def login_decorator(func) 라고 적혀있다. @login_decorator 장식을 한 함수가 파라미터로 전달이 된다.
    여기서는 post 함수가 전달이 되어진다.

  2. return wrapper 함수로 wrapper함수가 실행이 된다.

  3. request.headers.get('Authorization',None) 이 코드로 토큰을 받게된다. body 가 아니고 header 인 이유는 프론트엔드에서 header 로 전달이 된다.
    지금 이것은 아직 바이너리 로 된 긴 string 문자열이 된다.

  4. jwt.decode 해서 첫번째 인자에는 디코딩할 바이너리 string 그리고 두번째 인자는 key 값 과 세번째 인자는 algorithm 을 넣으면된다.

(토큰을 발행할때는 , 바이너리인 string 문자열이다. 이것을
header 에서 한번더 decode 해서 해독을 하게 되면 user.email을 얻게 되는것을 볼 수 있다 . )

  1. request.user = Account.object.get(email=payload["email"]
    request.user 에 Account.object.get 을 통해서 ,
    email 객체를 넣어주게 된다.

  2. return(func , request , *args , **kargs)

적용

import json
from django.views import View
from django.http import HttpResponse, JsonResponse
from account.decorators import login_decorator
from .models import Comment


class CommentView(View):
    @login_decorator
    def post(self, request):
        comment_data = json.loads(request.body)
        try:
            Comment(
                email=request.user.email,
                comment=comment_data['comment'],
            ).save()
            return HttpResponse(status=200)
        except KeyError:
            return JsonResponse({'message': 'INVALD_KEYS'}, status=400)

    def get(self, request):
        comment = Comment.objects.values()  # 한줄로 줄이기
        return JsonResponse({'comment': list(comment)}, status=200)
        

결과

 jakdu  ~  http -v http://localhost:8000/comment "Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6Impha2R1QGdtYWlsLmNvbSJ9.s0Io_fAFvz-_8oaVuJrWiFyVUnFzxmk_YQncU5QId3Y" comment="login test"
POST /comment HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6Impha2R1QGdtYWlsLmNvbSJ9.s0Io_fAFvz-_8oaVuJrWiFyVUnFzxmk_YQncU5QId3Y
Connection: keep-alive
Content-Length: 25
Content-Type: application/json
Host: localhost:8000
User-Agent: HTTPie/2.0.0

{
    "comment": "login test"
}

HTTP/1.1 200 OK
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Sun, 16 Feb 2020 11:51:19 GMT
Server: WSGIServer/0.2 CPython/3.7.6
X-Content-Type-Options: nosniff
X-Frame-Options: DENY



 jakdu  ~  http -v http://localhost:8000/comment "Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6Impha2R1QGdtYWlsLmNvbSJ9.s0Io_fAFvz-_8oaVuJrWiFyVUnFzxmk_YQncU5QId3Y" comment="login test2"
POST /comment HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6Impha2R1QGdtYWlsLmNvbSJ9.s0Io_fAFvz-_8oaVuJrWiFyVUnFzxmk_YQncU5QId3Y
Connection: keep-alive
Content-Length: 26
Content-Type: application/json
Host: localhost:8000
User-Agent: HTTPie/2.0.0

{
    "comment": "login test2"
}

HTTP/1.1 200 OK
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Sun, 16 Feb 2020 13:55:46 GMT
Server: WSGIServer/0.2 CPython/3.7.6
X-Content-Type-Options: nosniff
X-Frame-Options: DENY



 jakdu  ~  http -v http://localhost:8000/comment "Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6Impha2R1QGdtYWlsLmNvbSJ9.s0Io_fAFvz-_8oaVuJrWiFyVUnFzxmk_YQncU5QId3Y" comment="login test3"
POST /comment HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6Impha2R1QGdtYWlsLmNvbSJ9.s0Io_fAFvz-_8oaVuJrWiFyVUnFzxmk_YQncU5QId3Y
Connection: keep-alive
Content-Length: 26
Content-Type: application/json
Host: localhost:8000
User-Agent: HTTPie/2.0.0

{
    "comment": "login test3"
}

HTTP/1.1 200 OK
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Sun, 16 Feb 2020 14:02:27 GMT
Server: WSGIServer/0.2 CPython/3.7.6
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

profile
꾸준함이란 ... ?

0개의 댓글