5주간의 이야기 - 1

Dalbi·2021년 6월 1일
0
post-thumbnail
post-custom-banner

서론

마지막 블로그 포스트 이후 약 5주의 시간이 지났다. 그 사이 Python으로 진행된 하나의 프로젝트가 끝났고 node.js로 진행된 하나의 프로젝트가 현재 진행중이다.

두 프로젝트를 진행하며 사실 블로그에 올리고 싶었던 내용이 많았지만 게을렀던 과거의 나로인해 현재의 내가 그 역할을 맡게 되었다.(원망하지 말자... 원망하지 말자...)

Pyhon - 소셜 로그인

2021-04-21부터 2021-05-07까지 2주간 원티드를 모티브로 한 사이트 제작 프로젝트를 진행하였다. 내가 맡은 파트는 로그인부분이고 소셜 로그인을 포함하게 되었다.

소셜 로그인은 OAuth2 인증을 사용했고 카카오, 구글, 네이버로 가능하게 했다.

OAuth2란? Open Authorization2의 줄인말로 카카오, 구글, 네이버 등의 Authorization Server를 통해 회원 정보를 인증받아 Access Token을 발급받아 이 Access Token을 사용하여 타사의 API 서비스를 사용할 수 있다.

이번 프로젝트에서는 간단하게 Access Token을 이용해서 회원의 이름과 email을 가져와 데이터베이스에 저장하고 로그인과정을 마치도록 하였다.

아래는 코드이다.

< 카카오 소셜 로그인 >

< 구글 소셜 로그인 >

< 네이버 소셜 로그인 >

사실 소셜로그인은 백엔드와 프론트엔드가 각자 역할이 나누어져 있다. 프론트엔드의 경우 보통 Access token까지 발행을 맡고 백엔드의 경우 Access token을 받아 API 서비스를 통해 사용하는 역할을 맡는다. 위의 코드는 두 역할 모두 진행한 모습니다.

소셜 로그인 코드 내용

class KakaoGetCode(View):
    def get(self, request):

        return redirect("https://kauth.kakao.com/oauth/authorize?response_type=code&client_id={}&redirect_uri={}".format(kakao_client_id, kakao_redirect_url))

KaKaoGetCode로 설정한 url로 유저가 요청을 보내게되면 유저는 redirect로 설정된 주소로 보내지게 된다. 그러면 소셜 로그인 버튼을 눌렀을때 흔히 보게되는 아래와 같은 페이지로 가게된다.

유저가 이곳에서 로그인을 하고 인증과정을 거치면 kakao_redirect_url로 내가 설정한 페이지에 쿼리 스트링으로 code라는 값을 가지고 다시 접속을 한다.

class KakaoSignin(View):
    def get(self,request):
        code    = request.GET.get('code',None)
        url     = "https://kauth.kakao.com/oauth/token"
        headers = {"Content-type": "application/x-www-form-urlencoded;charset=utf-8"}
        body    = {'client_id'     : kakao_client_id,
                   'redirect_uri'  : kakao_redirect_url,
                   'code'          : code,
                   'client_secret' : kakao_client_secret,
                   'grant_type'    : 'authorization_code'}

        kakao_data    = requests.post(url, headers = headers, data = body).json()
        
        access_token  = kakao_data['access_token']

이제 이 code과 공식문서에서 요구하는 다양한 값(headers, body)을 동봉하여 정해진 url로 post요청을 보내면 이제 Access toke을 받을 수 있다.(Access token외에도 다양한 정보가 들어있으며 정보의 내용은 제공하는 서비스마다 다르다.)

여기까지가 프론트엔드에서 진행해야 하는 내용이며 여기서는 프론트엔드 없이 소셜 로그인 과정을 진행하기 위해 REST API를 통해 Access token을 받아왔음을 알린다.

이제부터가 백엔드에서 진행해야 하는 내용이다.

	user_info_url      = 'https://kapi.kakao.com/v2/user/me'
        user_info_headers  = {'Authorization': 'Bearer ' + access_token}

        user_info_data = requests.get(user_info_url, headers = user_info_headers).json()

        user_name  = user_info_data['properties']['nickname']
        user_email = user_info_data['kakao_account']['email']

이제 Access token을 요청할 url에 headers에 정해진 값으로 정보를 담아 get요청을 보내면 필요한 정보들을 받을수 있다. 이때 받을수 있는 정보는 어플리케이션 설정에 따라, 그리고 유저가 허용한 정보에 따라 달라진다.

        access_token = social_signin(user_name, user_email)
        
        if access_token == 'INVALID_EMAIL':
            return JsonResponse({"MESSAGE": "INVALID_EMAIL"}, status=401)

        return JsonResponse({'MESSAGE': 'SUCCESS', 'TOKEN' : access_token }, status=201)

이제 받아온 정보(여기서는 이메일과 이름)를 가지고 사이트를 이용할 수 있는 token을 발행해 주어야한다. 아래 코드가 이메일과 이름을 통해 jwt를 발행하는 함수이다.

def social_signin(name,email):
    if not email_validation(email):
        return 'INVALID_EMAIL'

    if not User.objects.filter(email=email).exists():
        User(name=name, email=email, position_id=1, is_social=1).save()

    user = User.objects.get(email=email)

    access_token = jwt.encode({'user_id': user.id}, SECRET_KEY, algorithm = algorithm)

    return access_token

코드를 보면 기존에 소셜 로그인을 했었던 이메일이라면 추가적인 저장없이 jwt를 발행하도록 하였다. 이로서 사용자는 회원가입 없이 사이트를 사용할 수 있게 되었다.

2편에서 계속..

profile
백엔드..?
post-custom-banner

0개의 댓글