안드로이드 어플을 만드는 과정에서 Naver Login 기능이 필요했습니다. 하지만 테스트 환경에서 DRF로 네이버 소셜로그인을 서술한 글이 없어 여러가지 글들을 참고해 기능을 만들어보았습니다. *Project에서는 결국 소셜로그인 기능을 네이티브로 구현하기로 했습니다. 여기서 서술하는 방법은 웹, 모바일 웹 등에서 사용할 수 있는 방법이라고 생각됩니다.
테스트 환경에서 DRF 에서 Naver Login이 가능하도록 설정하는 방법에 대해 작성해보도록 하겠습니다.
목차
1. 네이버 로그인 API 등록
2. settings.py
3. views.py
4. 실행해보기
1. 네이버 로그인 API 등록
네이버 로그인 API 를 사용하기 위해서는 우선적으로 "Naver Developers"에서 어플리케이션을 등록해야 합니다. 아래 주소로 접속해서 순서를 따라오시면 됩니다.
https://developers.naver.com/main/
모든 과정을 마친 다음 등록하기를 눌러줍니다.
그러면 위에서 설정했던 어플리케이션 이름이 아래처럼 나타납니다. 여기서 Client ID 와 Client Secret 은 네이버 로그인을 위한 View를 작성할 때 사용되기 때문에 따로 저장해두시면 됩니다.
우선 로그인 API 가 어떻게 동작하는지를 눈에 익혀두고 진행하도록 하겠습니다. 우리가 진행할 부분은 NAVER 로그인 API 이지만 네이버에는 정리된 것이 없어 KAKAO 의 로그인 진행 과정을 가지고 왔다. SOCIAL LOGIN의 경우 대부분 비슷한 로직을 갖고있기 때문에 KAKAO에서 제공해주는 로그인 진행 과정을 이해하면 NAVER 로그인 또한 이해할 수 있다.
2. settings.py 설정
본격적으로 프로젝트를 생성하고 소셜로그인을 위해 필요한 것들을 설치해보도록 하겠습니다. 저는 프로젝트를 VScode에서 진행했고, 가상환경 내에서 라이브러리들을 설치했습니다.
*VScode 에서 파이썬 설치 및 가상환경 설정을 잘 모르시는 분은 아래 링크를 타고 들어가서 똑같이 진행하시면 됩니다.
https://axce.tistory.com/64?category=991890
https://axce.tistory.com/65?category=991890
1) DjangoRestFramework 설치 및 Project 생성
# djangorestframework 설치
$ pip install djangorestframework
# project 생성
$ django-admin startproject setting
project 폴더의 명을 변경해줍니다.
2) secrets.json 파일 분리
프로젝트에 사용되는 보안이 필요한 Key 들을 따로 분리해 놓을 수 있는 파일을 만들어둡니다. 저는 Project 내용을 github에 올려 공유해놓을 예정이기 때문에 아래와 같이 Key 들을 분리하고, settings.py 파일에서 불러와서 사용합니다.
(1) SECRET_KEY
- 장고 프로젝트의 secret key 입니다.
(2) MAIN_DOMAIN
- Naver Developers 에서 설정했던 서비스 URL 입니다. 현재는 테스트 환경이기 때문에 IP 주소를 사용했습니다.
(3) NAVER_CLIENT_ID
- 이전에 받았던 네이버에서 제공해주는 Client ID 입니다.
(4) NAVER_CLIENT_SECRET
- 마찬가지로 이전에 받았던 네이버에서 제공해주는 Client Secret 입니다.
이제 이렇게 설정한 Key 들을 서버가 run 될 때 settings.py 파일에서 설정되도록 아래 코드를 settings.py 파일에 추가해줍니다. *settings.py 파일에 있는 SECRET_KEY = "" 부분은 삭제해주시기 바랍니다.
# SocialLoginProject/setting/settings.py
...
import os
import json
import sys
BASE_DIR = Path(__file__).resolve().parent.parent
# secrets.json 파일을 찾아줍니다.
SECRET_BASE_FILE = os.path.join(BASE_DIR, 'secrets.json')
# secrets.json 파일을 읽고, json key/value 값들을 secrets에 할당합니다.
secrets = json.load(open(SECRET_BASE_FILE))
# setattr을 이용해 key 값은 변수명, value 값은 값으로 각 변수에 할당합니다.
for key, value in secrets.items():
setattr(sys.modules[__name__], key, value)
...
제대로 되는지 확인해보려면 밑에 print(SECRET_KEY) 등과 같이 추가해서 서버를 돌려보면 됩니다. 아래와 같이 sercrets.json 에서 지정한 값이 출력되는 것을 확인하실 수 있습니다.
3) 추가 기능 Install
# allauth : django에서 소셜로그인이 가능하도록 해주는 라이브러리
$ pip install django-allauth
# dj-rest-auth : REST API 환경에서 User 관리를 쉽게 해주는 라이브러리(allauth 기반)
$ pip install dj-rest-auth
# JWT 를 사용하기 위한 라이브러리
$ pip install djangorestframework-simplejwt
이 기능들을 settings.py 파일에 추가해주도록 하겠습니다.
# SocialLoginProject/setting/settings.py
INSTALLED_APPS = [
...
# dj_rest_auth 의 registration 을 사용하려면 app에 추가해주어야 한다.
'django.contrib.sites',
# DRF
'rest_framework',
# dj_rest_auth 를 사용하려면 아래 app이 선행되어야 한다.
'rest_framework.authtoken',
# Social 로그인을 위한 app
'allauth',
'allauth.account',
'allauth.socialaccount',
# Naver
'allauth.socialaccount.providers.naver',
# dj_rest_auth
'dj_rest_auth',
'dj_rest_auth.registration',
# token
'rest_framework_simplejwt',
]
4) User App
# user App 설치
$ python manage.py startapp user
user app 의 설정을 위한 것들은 아래 글을 참고해주시면 됩니다. 아래 글에서 실제로 제가 만든 모델은 1, 2 과정까지의 모델입니다. JWT 는 simplejwt를 사용할 것이기 때문에 3번부터는 읽지 않으셔도 됩니다. 또 제가 깃허브에 올려놓은 프로젝트에서 user app 의 models.py 와 managers.py 는 복사해서 붙여넣으셔도 됩니다.
https://axce.tistory.com/99?category=991890
이제 settings.py 파일에 몇가지 설정을 추가해주도록 하겠습니다.
# SocialLoginProject/setting/settings.py
INSTALLED_APPS = [
...
# myapp
'user',
]
# SET USER MODEL
AUTH_USER_MODEL = 'user.User'
5) 기타 설정
# SocialLoginProject/setting/settings.py
from datetime import timedelta
# rest framework 에 대한 설정
REST_FRAMEWORK = {
# 기본 인증에 대한 설정
'DEFAULT_AUTHENTICATION_CLASSES': (
# dj_rest_auth 의 인증 절차 중 JWTCookieAuthentication을 사용
'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
),
# 허가에 대한 설정
'DEFAULT_PERMISSION_CLASSES': (
# 인증이 완료된 사용자에 한해서 접근 허가
'rest_framework.permissions.IsAuthenticated',
)
}
# cookie key 와 refresh cookie key 의 이름을 설정
JWT_AUTH_COOKIE = 'sociallogin-auth'
JWT_AUTH_REFRESH_COOKIE = 'sociallogin-refresh-token'
# JWT 사용을 위한 설정
REST_USE_JWT = True
# simplejwt 에 대한 설정
SIMPLE_JWT = {
# access token 의 유효기간
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
# refresh token 의 유효기간
'REFRESH_TOKEN_LIFETIME': timedelta(days=2),
# 토큰에 들어갈 알고리즘
'ALGORITHM': 'HS256',
# 토큰을 만드는데 사용할 secret key
'SIGNING_KEY': SECRET_KEY,
}
다음으로는 Social Login 을 위한 Provider를 설정해보겠습니다. secrets.json 파일을 열어 아래와 같이 추가 입력해줍니다.
{
"SECRET_KEY":"django-insecure-u^dwaltg9ji$czy^1=z=d(6ue=(-b5pb316l$bhi5j*uxgu95b",
"MAIN_DOMAIN":"http://127.0.0.1:8000",
"NAVER_CLIENT_ID":"Qd5paRgcxlgMxClKlirF",
"NAVER_CLIENT_SECRET":"E98qZUqjxy",
"STATE":"NAVER_LOGIN_STRING",
"SOCIALACCOUNT_PROVIDERS":{
"naver":{
"APP":{
"client_id":"NAVER_CLIENT_ID",
"secret":"NAVER_CLIENT_SECRET",
"key":""
}
}
}
}
"STATE" 는 Naver에서 사이트 간 요청시 위조를 방지하기 위해 사용하는 string 값으로 지금 저는 "NAVER_LOGIN_STRING"으로 설정했지만 랜덤한 string으로 설정해주면 됩니다.
"SOCIALACCOUNT_PROVIDERS" 는 naver, kakao 등에 접근할 수 있도록 하기 위해 추가해줍니다. APP 내부에 있는 client_id, secret 등은 settings.py 에서 차례로 정의되면서 값들이 채워지게 됩니다.
이것으로 settings.py 의 설정은 마치겠습니다.
3. Views.py
settings.py , models.py 모두 세팅이 끝났으면 views.py 에서 Login 을 위한 로직을 구현 할 차례입니다. 우선 네이버의 Document를 확인해보도록 하겠습니다.
처음 해야 할 부분은 네이버 로그인 연동을 진행하기 위해 '네이버 로그인 URL'을 생성해야 합니다. 사용자가 로그인 버튼을 누르면 네이버 로그인 창으로 접속 할 수 있도록 하는 기능입니다. 아래를 보고 어떻게 view를 구성하면 좋을지 확인해보겠습니다.
우선 요청을 보낼 URL 과 요청 변수 정보를 확인할 수 있습니다. 이것을 토대로 views.py 를 1차적으로 작성해보겠습니다.
# SocialLoginProject/user/API/views.py
# settings.py 에서 설정한 MAIN_DOMAIN 등을 불러오기 위해 import 함
from django.conf import settings
from django.shortcuts import redirect
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny
# main domain(http://127.0.0.1:8000)
main_domain = settings.MAIN_DOMAIN
# DRF의 APIView를 상속받아 View를 구성
class NaverLoginAPIView(APIView):
# 로그인을 위한 창은 누구든 접속이 가능해야 하기 때문에 permission을 AllowAny로 설정
permission_classes = (AllowAny,)
def get(self, request, *args, **kwargs):
client_id = settings.NAVER_CLIENT_ID
response_type = "code"
# Naver에서 설정했던 callback url을 입력해주어야 한다.
# 아래의 전체 값은 http://127.0.0.1:8000/user/naver/callback 이 된다.
uri = main_domain + "/user/naver/callback"
state = settings.STATE
# Naver Document 에서 확인했던 요청 url
url = "https://nid.naver.com/oauth2.0/authorize"
# Document에 나와있는 요소들을 담아서 요청한다.
return redirect(
f'{url}?response_type={response_type}&client_id={client_id}&redirect_uri={uri}&state={state}'
)
class NaverCallbackAPIView(APIView):
permission_classes = (AllowAny,)
def get(self, request, *args, **kwargs):
try:
print("성공")
except:
print("실패")
이제 위의 view에 접근하기 위해 urls.py 파일을 설정해보겠습니다.
# SocialLoginProject/setting/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
# user의 urls로 접근
# 여기서 user/ 로 url을 작성한 이유는 Naver 로그인 API를 설정할 때
# callback 함수의 url을 "http://127.0.0.1:8000/user/naver/callback"으로
# 지정했기 때문이다.
path('user/', include('user.API.urls'))
]
# SocialLoginProject/user/API/urls.py
from django.urls import path, include
from user.API.views import (
NaverLoginAPIView, NaverCallbackAPIView
)
urlpatterns = [
path('naver/login', NaverLoginAPIView.as_view()),
# 여기서 callback url은 반드시 Naver 로그인 API 설정 당시 작성했던
# callback url로 지정해주어야 한다. 앞의 user/ 까지 더해지면
# http://127.0.0.1:8000/user/naver/callback 이 된다.
path('naver/callback', NaverCallbackAPIView.as_view()),
]
4. 실행해보기
1차적으로 설정해야 하는 부분, 구현해야 하는 부분은 끝났습니다. 이제 callback 함수에서 제대로 반환되어 오는지 확인해보도록 하겠습니다. 이 부분은 아래와 같이 Naver Document에 오류일 경우와 아닐 경우를 나누어서 반환해줍니다. 그 부분을 확인해보겠습니다.
추가된 APP 을 설치하기 위해 migration 을 진행해주세요.
$ python manage.py makemigrations
$ python manage.py migrate --run-syncdb
위와 같이 view에 get 요청을 보내면 네이버로그인 인증 요청 부분으로 redirect 됩니다. 이미 브라우저 환경에 Naver가 로그인 되어 있으면 아래와 같은 화면이 나오고, 아닌 경우에는 아이디와 비밀번호를 입력하는 창이 나옵니다.
여기서 동의하고 진행해보겠습니다.
그러면 error 는 발생하지만 아래와 같이 code 와 state 값이 정상적으로 받아오는 것을 확인할 수 있습니다.
다음 2편에서는 이제 본격적으로 view를 수정해 Login 기능을 완성해보도록 하겠습니다.
참고자료
'BackEnd > DRF' 카테고리의 다른 글
DRF - 소셜 로그인 -2(Naver Login) (0) | 2022.07.06 |
---|---|
ImageField 사용 방법(Upload Image) (0) | 2022.01.13 |
DRF - 중첩데이터(nested data) 받는 방법(NestedSerializerMixin) (0) | 2022.01.12 |