관리 메뉴

Storage Gonie

48. (app3) Django 소셜로그인 구현하기(페이스북, 다른건 응용가능) 본문

웹개발/Django 웹서비스 개발(인프런)

48. (app3) Django 소셜로그인 구현하기(페이스북, 다른건 응용가능)

Storage Gonie 2019. 2. 27. 17:13
반응형

0. OAuth2란? 

- 검색해보기


1-1. Github 홈페이지에서 "django allauth"를 검색하고, 최상단의 것을 클릭한다.

https://github.com/pennersr/django-allauth

https://github.com/omab/django-social-auth

- auth는 보통 위의 두가지가 사용되는데 위의 것이 좀 더 최신의 것이다.

1-2. 아래의 Documentation을 클릭한다.

1-3. Installation - Django 를 클릭하면 장고에서 auth를 사용할 수 있게 할 수 있고, 나와있는 순서대로 하면 된다.

https://django-allauth.readthedocs.io/en/latest/installation.html#django

2-1. 가상환경을 실행시키고 django-allauth 모듈을 설치한다.

- "source activate 가상환경명"

- "pip install django-allauth"


2-2. 오픈소스로 배포할 때 설치해야할 모듈을 공유할 때 알아두면 좋은 것.(넘어가도 됨)

- "pip freeze" 를 하면 어떤 모듈이 설치되어 있는지 알 수 있다.

- "pip freeze > requirement.txt" 하면 파일에 저장할 수 있다.

requirement.txt에서 필요한 모듈만 남겨두고 공유해주면 좋다.


2-3. 아래의 코드를 settings.py의 TEMPLATES의 OPTIONS의 context_processors에 추가해준다.

# `allauth` needs this from django
'django.template.context_processors.request',
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
# `allauth` needs this from django
'django.template.context_processors.request',
],
},
},
]

2-4. 아래의 코드를 settings.py의 맨 아래에 그대로 복붙한다.

AUTHENTICATION_BACKENDS = (
# Needed to login by username in Django admin, regardless of `allauth`
'django.contrib.auth.backends.ModelBackend',

# `allauth` specific authentication methods, such as login by e-mail
'allauth.account.auth_backends.AuthenticationBackend',
)

 2-5. 아래의 코드를 settings.py의 INSTALLED_APPS 값에 삽입해준다.

- django.contrib.auth도 포함되어 있었는데 그건 INSTALLED_APPS에 이미 존재하기 때문에 지워줬다.

- django.contrib.messages도 포함되어 있었는데 그건 강의에서 사용하지 않아서 지워줬다.

'django.contrib.sites',  # allauth

'allauth',
'allauth.account',
'allauth.socialaccount',
INSTALLED_APPS = [
'kilogram',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'django.contrib.sites', # allauth

'allauth',
'allauth.account',
'allauth.socialaccount',
]

 2-6. 아래의 코드를 settings.py의 INSTALLED_APPS 값에 삽입해준다.

- 도큐먼트에서 보면 kakao, naver, 등의 다양한 것에서도 이용 가능하다는 것을 알 수 있다.

'allauth.socialaccount.providers.facebook',
INSTALLED_APPS = [
'kilogram',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'django.contrib.sites', # allauth

'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
]

 2-7. 아래의 코드를 settings.py의 맨 아래에 추가해준다.

SITE_ID = 1

 2-8. 도큐먼트 페이지에서 Providers - Facebook 클릭


 2-9. 아래의 코드를 settings.py의 맨 아래에 추가해준다.

- FIELDS는 페이스북 계정에서 가져올 정보를 의미하는데 이를 조금 수정해서 필요한 것만 가져올 예정

- LOCALE_FUNC로 이대로 하면 오류가 발생하므로 아래의 코드로 수정해준다.

- VERSION도 문서에는 2.12로 나와있는데 실제 최신 버전은 2.9이므로 이렇게 수정

SOCIALACCOUNT_PROVIDERS = {
'facebook': {
'METHOD': 'oauth2',
'SCOPE': ['email', 'public_profile', 'user_friends'],
'AUTH_PARAMS': {'auth_type': 'reauthenticate'},
'INIT_PARAMS': {'cookie': True},
'FIELDS': [
'id',
'email',
'name',
'first_name',
'last_name',
'verified',
'locale',
'timezone',
'link',
'gender',
'updated_time',
],
'EXCHANGE_TOKEN': True,
'LOCALE_FUNC': 'path.to.callable',
'VERIFIED_EMAIL': False,
'VERSION': 'v2.12',
}
}

# Allauth-facebook
SOCIALACCOUNT_PROVIDERS = {
'facebook': {
'METHOD': 'oauth2',
'SCOPE': ['email', 'public_profile', 'user_friends'],
'AUTH_PARAMS': {'auth_type': 'reauthenticate'},
'INIT_PARAMS': {'cookie': True},
'FIELDS': [
'id',
'email',
'name',
'first_name',
'last_name',
'friends',
'verified',
],
'EXCHANGE_TOKEN': True,
'LOCALE_FUNC': lambda request: 'ko_KR',
'VERIFIED_EMAIL': False,
'VERSION': 'v2.9',
}
}

 2-10. 아래의 코드를 settings.py의 맨 아래에 추가해준다.

- SMTP 메일서버 세팅이 안되어 있기 때문에 에러가 나는데 이를 임시방편으로 해결하기 위해 아래의 코드를 추가해 주는 것이다.

- 실제 이를 구현하고 싶다면 구글의 Gmail 또는 AWS을 이용해서 smtp 서버를 설정해주면 된다.

- 검색 키워드는 'gmail smtp server settings'

- gmail smtp server settings이란? : 이메일 소프트웨어 프로그램으로 gmail계정에서 메일을 보내고 싶을 때 필요한 것.

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

 2-11. 도큐먼트 페이지에서 Installation - Django로 다시 돌아와 mysite/urls.py를 수정해준다.

- 새로 추가해준 allauth.urls가 주석처리해준 부분을 대신 처리해주기 때문에 주석처리를 하던 지우던 해준다.

- 그러면 url name이 또 달라지기 때문에 base.html에서 사용한 url name의 수정이 필요한데 이는 3-8에서 수정해주는데 일단 여기까지만 하고 넘어가자.

urlpatterns = [
url(r'^$', login_required(kilogram_views.IndexView.as_view()), name='root'),
url(r'^admin/', admin.site.urls),
url(r'^kilogram/', include('kilogram.urls')),
url(r'^accounts/', include('django.contrib.auth.urls')), # 인증관련된 views는 미리 정의가 되어있어 url만 추가해주면 됨.
url(r'^accounts/signup$', kilogram_views.CreateUserView.as_view(), name="signup"), # 회원가입 화면
url(r'^accounts/signup/done$', kilogram_views.RegisteredView.as_view(), name="create_user_done"), # 회원가입이 완료된 화면
]
urlpatterns = [
url(r'^$', login_required(kilogram_views.IndexView.as_view()), name='root'),
url(r'^admin/', admin.site.urls),
url(r'^kilogram/', include('kilogram.urls')),
url(r'^accounts/', include('allauth.urls')),
#url(r'^accounts/', include('django.contrib.auth.urls')), # 인증관련된 views는 미리 정의가 되어있어 url만 추가해주면 됨.
#url(r'^accounts/signup$', kilogram_views.CreateUserView.as_view(), name="signup"), # 회원가입 화면
#url(r'^accounts/signup/done$', kilogram_views.RegisteredView.as_view(), name="create_user_done"), # 회원가입이 완료된 화면
]


 2-12. 다음의 명령어를 실행해 지금까지 문제가 없는지 확인.

- "python manage.py makemigrations" 했을 때 이상없이 잘 되면 문제가 없음.


3-1. 페이스북 for developers 가입하기

- https://developers.facebook.com/apps/

3-2. 가입과 동시에 앱 등록하기

3-3. 테스트앱 만들기

- 테스트 앱 만들기 클릭.

- 일반 사용자가 사용하게 되는 서비스라면 새 앱 만들기를 대신 클릭해야한다.

3-4. 좌측에 Facebook 로그인 - 설정을 클릭 후, 유효한 OAuth 리디렉션 URI에 '127.0.0.1:8000'를 추가해준뒤 변경내용을 저장해줌.

- 실제 서비스되는 앱이라면 저 URI가 아닌 서버의 도메인을 입력해줘야 할 것임

- 페이스북이 인증을 진행하고 그 인증결과를 돌려받을 주소를 넣는 것임.

3-5. 좌측의 설정 - 기본설정에서 앱ID와 앱 시크릿 코드를 볼수있는 상태로 둠.

3-6. "http://localhost:8000/admin/"접속 해서 사이트 추가 또는 변경

- 디폴트로 example.com이 들어가 있을텐데 이를 수정해주는 방식으로 해야한다.

- 왜냐하면 settings.py에 "SITE_ID=1"을 추가한거랑 연결되어야 하기 때문임.

- 추가하는 방식으로 만들게 되면 settings.py에서 "SITE_ID=1"을 "SITE_ID=2"로 해주어야 한다.



3-7. 소셜 어플리케이션을 아래와 같이 추가해준다.

- 클라이언트 아이디는 앱 ID이고, 비밀 키는 앱 시크릿코드를 의미하는데 이를 복사 붙여넣기 해서 채워준다.

- 맨 아래에의 Sites에서는 선택할 수 있는 127.0.0.0.1:8000이 있는데 이를 오른쪽으로 옮겨준다.


3-8.  2-11에서 지워준 url들 때문에 사이트 화면이 정상적으로 뜨지 않아 아래와 같이 수정해줘야함

- 기존에 장고의 auth를 사용했었는데 지금은 allauth를 사용하므로 그런것임
- "localhost:8000/accounts" 에 접속하면 화면은 뜨지 않지만 allauth가 지원하는 url name들이 나옴

- base.html에서 url 이름을 아래에 뜨는것과 맞게 수정해줌.


{% if user.is_active %}
<li><a href="{% url 'login' %}"> <span class="glyphicon glyphicon-heart"></span> {{user.username}}</a></li>
<li><a href="{% url 'logout' %}">Logout</a></li>
{% else %}
<li><a href="{% url 'login' %}"> <span class="glyphicon glyphicon-user"></span> Login</a></li>
<li><a href="{% url 'admin:index' %}">Admin</a></li>
{% endif %}
{% if user.is_active %} <!-- 로그인된 상태에서 계정의 이름을 눌렀을 때 로그인 페이지를 보여줄 필요가 없으므로 링크를 지움 -->
<li><a href="#"> <span class="glyphicon glyphicon-heart"></span> {{user.username}}</a></li>
<li><a href="{% url 'account_logout' %}">Logout</a></li>
{% else %}
<li><a href="{% url 'account_login' %}"> <span class="glyphicon glyphicon-user"></span> Login</a></li>
<li><a href="{% url 'admin:index' %}">Admin</a></li>
{% endif %}

3-9.  로그아웃을 하고 페이스북으로 로그인이 가능해졌다.

- facebook을 클릭하면 페이스북 로그인 페이지로 넘어가며 페북의 비밀번호와 아이디를 입력하면 로그인이 가능하다.

- 아래에서 보여지는 '킬로그램' 한글 이름은 admin사이트에서 입력해준 것.

- 현재는 테스트 앱으로 진행하고 있기 때문에 내 아이디로만 되는데, 테스터를 추가해주면 다른사람도 테스트할 수 있게됨.(페이스북 계정의 이름을 입력하면 됨)

3-10.  페이스북을 통해 로그인에 성공했다면 admin에서 회원가입된 정보를 확인해보자

- 페이스북으로부터 받아온정보를 토대로 사용자가 등록된 것을 알 수 있다.

- 소셜계정란에서 보면 이름, 이메일, 친구가 몇명인지 등의 정보가 담겨져 있다.







3-11.  allauth를 사용하면서 부실해진 템플릿을 수정해주자

- templates/account폴더를 만든다.

templates/kilogram에 있는 base.html 파일을 위의 폴더 아래로 옮겨준다.

- templates/kilogram에 있는 photo_list.html맨 윗라인의 {% extends 'kilogram/base.html' %} 을 {% extends 'accounts/base.html' %}로 고쳐준다.

- templates/kilogram에 있는 upload.html맨 윗라인의 {% extends 'kilogram/base.html' %} 을 {% extends 'accounts/base.html' %}로 고쳐준다.

- 로그인 페이지에 base.html이 아래와 같이 추가된 것을 볼 수 있다.

3-12.  allauth에서 사용되는 로그인, 로그아웃 관련된 템플릿을 수정하고 싶을 때?

- allauth 깃허브(https://github.com/pennersr/django-allauth/tree/master/allauth/templates/account)에서 allauth/templates/account/ 경로에 가보면 사용되는 템플릿들이 있는데 이 코드와 파일이름을 그대로 가져와 account폴더 밑에 넣어주고 수정해주면 된다. 그러면 디폴트 파일이 연결되지 않고 사용자가 정의한 파일이 불려진다.

- 아래의 코드는 예시로 login.html을 가져와본 것이다.

{% extends "account/base.html" %}

{% load i18n %}
{% load account socialaccount %}

{% block head_title %}{% trans "Sign In" %}{% endblock %}

{% block content %}

<h1>{% trans "Sign In" %}</h1>

{% get_providers as socialaccount_providers %}

{% if socialaccount_providers %}
<p>{% blocktrans with site.name as site_name %}Please sign in with one
of your existing third party accounts. Or, <a href="{{ signup_url }}">sign up</a>
for a {{ site_name }} account and sign in below:{% endblocktrans %}</p>

<div class="socialaccount_ballot">

<ul class="socialaccount_providers">
{% include "socialaccount/snippets/provider_list.html" with process="login" %}
</ul>

<div class="login-or">{% trans 'or' %}</div>

</div>

{% include "socialaccount/snippets/login_extra.html" %}

{% else %}
<p>{% blocktrans %}If you have not created an account yet, then please
<a href="{{ signup_url }}">sign up</a> first.{% endblocktrans %}</p>
{% endif %}

<form class="login" method="POST" action="{% url 'account_login' %}">
{% csrf_token %}
{{ form.as_p }}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<a class="button secondaryAction" href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
<button class="primaryAction" type="submit">{% trans "Sign In" %}</button>
</form>

{% endblock %}


3-13.  사용되지 않는 폴더인 templates/registration 폴더는 삭제해버려도 된다.

- 코드참고를 위해 삭제는 하지 않았음.


4-1. 앱 실제 사용자들에게 공개(1)

- 실제 서비스중인것만 하게끔 되어있어서 좀 많이 번잡함

- 테스트앱이 아닌 본래의 앱을 클릭해 들어간다.

- 앱 검수를 클릭한다.

- 필요한 권한을 요청한 후 검수를 위해 제출한다.

- 여기엔 실제 왜 이 권한이 필요한지, 앱 내에서 얻은 정보가 어떻게 사용되는지 명시하는 파일을 업로드 해줘야한다.


4-2. 앱 실제 사용자들에게 공개(2)

- 제품추가를 눌러 페이스북 로그인을 추가한 뒤 설정에서 유용한 OAuth 리디렉션 URI를 입력해준다.


4-3. 앱 실제 사용자들에게 공개(3)

- 좌측에서 설정 - 기본설정에서 앱ID와 앱 시크릿 코드를 보고

- 3-7 과 같이 이를 admin에서 클라이언트ID, 비밀키를 변경해준다.


4-4. 앱 실제 사용자들에게 공개(4)

- admin페이지의 url 을 코드에서 삭제해준다.



반응형
Comments