장고 소셜 로그인(allauth 사용)

Sam (토론 | 기여)님의 2021년 11월 6일 (토) 11:16 판

1 개요

유명하지 않은 사이트의 계정을 다 기억하는 건 참 어려운 일. 이럴 땐 공신력을 갖춘 외부 서비스의 인증기능에 위임하여 사용하면 편하다.

2 사전작업

pip install django-allauth

2.1 settings.py 설정

INSTALLED_APPS = [하위에 다음과 같은 내용들을 추가해 넣어준다.

'django.contrib.sites',  # 사이트 정보를 설정하기 위해 필요
# allauth 관련 앱 목록 추가
'allauth',
'allauth.account',  # 가입한 계정을 관리하기 위한 것.
'allauth.socialaccount',  # 소셜 계정을 관리하기 위한 것.
# 사용할 외부기능을 추가한다.
'allauth.socialaccount.providers.naver',
'allauth.socialaccount.providers.google',

#이미 있다면, 하위에 추가.
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',
]

#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 문서에서 참고하면 된다.
서비스 설명
네이버
구글 구글 API 콘솔에서 진행한다.

API를 사용하기 위해선 프로젝트가 있어야 한다. 프로젝트를 만들고..

좌측 메뉴의 '사용자 인증 정보' 선택 > OAuth 클라이언트 ID를 만든다.


API를 신청한다.

다른 곳에선... 사이트들에 서비스하는 사이트(http://127.0.0.1:8000/)를 등록하는데... 일단 안하고 진행해볼까?


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')