1 개요
sns 로그인. 유명하지 않은 사이트의 계정을 다 기억하는 건 참 어려운 일. 이럴 땐 공신력을 갖춘 외부 서비스의 인증기능에 위임하여 사용하면 편하다.
1.1 사용
기본적으로 username 필드에 정보를 담아준다. 자동으로 user1, user2, user3... 순으로 생성해준다. 장고에서 사용하는 AUTH 모델의 객체를 지우면 소셜계정 정보도 함께 지워진다.
1.2 들어가기 전에
- 커스텀 유저 모델을 작성하자.
- - 소셜 로그인을 구현한 후 커스텀 유저 만들기를 진행하는 중 DB를 지우고 말았다. 결국 작업을 다시 수행해야 해서 불편하다.
- - 이후 조금이라도 커스텀 유저모델을 사용할 기미가 보인다면 이를 미리 만들어 둔 후에 소셜 로그인을 구현하는 편이 좋다.
- - 커스텀 모델 작성 시 username 필드를 만들어두어야 한다.(sns login에서 사용하는 필드)
2 사전작업
pip install django-allauth
2.1 settings.py 설정
과정 | 설명 | 코드 |
---|---|---|
INSTALLED_APPS
|
INSTALLED_APPS 하위에 우측 앱들을 추가한다.
|
'django.contrib.sites', # 사이트 정보를 설정하기 위해 필요
# allauth 관련 앱 목록 추가
'allauth',
'allauth.account', # 가입한 계정을 관리하기 위한 것.
'allauth.socialaccount', # 소셜 계정을 관리하기 위한 것.
|
INSTALLED_APPS 하위에 서비스 해준 sns 계정을 추가한다.
사용 가능한 공급자는 다음 링크에서 확인하자. |
# 사용할 외부기능을 추가한다.
'allauth.socialaccount.providers.naver',
'allauth.socialaccount.providers.google',
| |
AUTHENTICATION_BACKENDS | AUTHENTICATION_BACKENDS 하위에 추가한다.
(일반적으로 없어, 우측의 코드를 다 써주면 된다.) |
# 이미 있다면, 하위에 추가.
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',
]
|
context_processors | TEMPLATES의 하위의 context_processors 아래에 'django.template.context_processors.request',를 추가해넣는다. | 'context_processors': [
'django.template.context_processors.request',
...
|
2.2 urls.py 설정
다음과 같이 url을 추가해준다.
urlpatterns = [
path('accounts/', include('allauth.urls')), # allauth의 기능을 accounts라는 주소 아래 담는다.
여기까지 하고 DB에 반영을 해주면 admin에서 '소셜 계정'이라는 모델집단을 볼 수 있다.
python manage.py migrate
그러면 다음과 같은 에러를 만난다.
django.contrib.sites.models.Site.DoesNotExist: Site matching query does not exist.
앱에 'django.contrib.sites'가 추가되었기 때문에 발생하는 에러인데, settings.py 아무데나 SITE_ID = 1을 지정해주면 된다. SITE_ID=1 # 무슨의미일까?
2.3 site 설정
admin 페이지에서 본인의 도메인을 사이트에 등록한다.
2.4 각 서비스 API 받기
- 각 서비스에서 받은 API는 관리자페이지에서
소셜계정>소셜어플리케이션 추가
에서 등록한다. - 서비스 url은 로컬환경에서 개발중이라면 http://localhost:포트번호 형식으로 등록한다.
- callback URL은 allauth 문서에서 참고하면 된다.
- 아래 과정을 진행하다가 소셜어플리케이션 객체를 작성하면
FOREIGN KEY constraint failed
에러를 만나기도 하는데... 이는 DB를 밀고 새로migrate
를 진행하면 문제 없이 진행된다.(역시... 회원관리 모델은 의존성 문제 때문에 에러가 많이 생기니, 프로젝트의 극초반에 진행해주어야 한다.)
서비스 | 설명 |
---|---|
네이버 |
|
구글 | 구글 API 콘솔에서 진행한다.
API를 사용하기 위해선 프로젝트가 있어야 한다. 프로젝트를 만들고.. 좌측 메뉴의 '사용자 인증 정보' 선택 > OAuth 클라이언트 ID를 만든다.
|
3 탬플릿 만들기
다음과 같은 형태로 로그인 버튼을 넣어 login.html을 수정한다.
allauth에서 제공하는 탬플릿에서 조금 끌어와 만들었다.
{% load static %}
{% static 'social_login/naver_login.png' as naver_button %}
{% static 'social_login/naver_login_hover.png' as naver_button_hover %}
<!--소셜로그인 기능 불러오기.-->
{% load i18n %}
{% load account socialaccount %}
{% get_providers as socialaccount_providers %}
<div class="panel-heading">
소셜로그인
</div>
<div class="panel-body text-center">
</div>
<ul class="socialaccount_providers">
{% for provider in socialaccount_providers %}
{% if provider.id == "openid" %}
{% for brand in provider.get_brands %}
<li>
<a title="{{brand.name}}"
class="socialaccount_provider {{provider.id}} {{brand.id}}"
href="{% provider_login_url provider.id openid=brand.openid_url process=process %}"
>{{brand.name}}</a>
</li>
{% endfor %}
{% endif %}
<!--제공자에 따라 만들어짐.-->
{% if provider.name == "Naver" %}
<div class="pull-left">
<a href="{% provider_login_url provider.id process=process scope=scope auth_params=auth_params %}">
<img src="{{ naver_button }}"
onmouseover="this.src='{{ naver_button_hover }}'"
onmouseleave="this.src='{{ naver_button }}'"height="34">
</div>
{% else %}
<li>
<a title="{{provider.name}}" class="socialaccount_provider {{provider.id}}"
href="{% provider_login_url provider.id process=process scope=scope auth_params=auth_params %}">{{provider.name}}</a>
</li>
{% endif %}
{% endfor %}
4 확인
만들어진 탬플릿에서 네이버나 구글 따위의 제공자 버튼을 클릭하면 회원가입과 로그인이 이루어진다. 이 확인은 관리자 페이지에서 확인 가능하다.
관리자페이지의 소셜계정 앱 안의 소셜계정 모델이 추가되는 것과 동시에 기본 인증앱의 Users 모델에 새로운 모델이 추가되어 있다.
5 기존 회원관리 뷰 수정
회원관리 뷰에서 회원가입 후에 자동으로 login을 시키는 경우, 기존 뷰를 수정해주어야 한다. 이번에 백엔드를 2개 사용하게 되었기 때문에 백엔드 옵션값을 주어야 한다.
그렇지 않으면 You have multiple authentication backends configured and therefore must provide the `backend` argument or set the `backend` attribute on the user. 라는 에러가 나타난다.
다음과 같은 형태로 고쳐주어야 한다.
login(request, user, backend='django.contrib.auth.backends.ModelBackend')