🐲

DjangoでGoogleログイン実装

2024/01/07に公開

はじめに

最近、DjangoでのWeb開発に挑戦しており、ソーシャルログイン機能を実装する機会があったので、流れをまとめてみました。

基本的には以下の記事に沿ってやってみました。作業の流れがわかりやすく、非常にありがたかったです。
https://self-methods.com/django-social-auth-app/

パッケージインストール

$ pip install social-auth-app-django

settings.pyへの記述

settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'social_django' # ここに追加
]

マイグレーションします。

$ python manage.py migrate

続いて、TEMPLATESへの記述をします。

settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        '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',
                'social_django.context_processors.backends',  # 追加
                'social_django.context_processors.login_redirect',  # 追加
            ],
        },
    },
]

次に、AUTHENTICATION_BACKENDSという項目を追加します。

settings.py
#追加
AUTHENTICATION_BACKENDS = (
 'social_core.backends.open_id.OpenIdAuth',  
  'social_core.backends.google.GoogleOpenId',  
 'social_core.backends.google.GoogleOAuth2',  
 'django.contrib.auth.backends.ModelBackend',
)

URLの追加

urls.py
from django.conf.urls import include
from django.urls import path
from django.contrib import admin
from django.contrib.auth import views as auth_views
from . import views

urlpatterns = [
     path('admin/', admin.site.urls),
    path('', include('appname.urls')), #アプリのURLはappname/urls.pyで管理

    path('logout/', auth_views.LogoutView.as_view(), name='logout'), #追加
    path('auth/', include('social_django.urls', namespace='social')), #追加
   
]

Google OAuth IDとキーの取得

基本的には以下の記事に従ってIDとキーを取得します。
https://support.google.com/workspacemigrate/answer/9222992?hl=ja

承認済みのリダイレクトURIには

http://127.0.0.1:8000/auth/complete/google-oauth2/
http://localhost:8000/auth/complete/google-oauth2/

を追加します。
取得できたら settings.pyへ記述。

settengs.py
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = 'xxxxxxxx'  
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = 'xxxxxxxxx'

templates作成

・templates/registration/login.html
・templates/registration/logged_out.html
をそれぞれ作成。中身は記述していません。

ログインボタン、ログアウトボタンの設置

私の場合はtop.htmlとbase.htmlに設置しましたが、適宜htmlファイルに以下を記述するだけでログインボタン、ログアウトボタンが設置できます。

ログインボタン

top.html
...

<a href="{% url 'social:begin' 'google-oauth2' %}">Googleでログイン</a>

...

ログアウトボタン

base.html
...

<a href="{% url 'logout' %}">ログアウト</a>

...

ひとまず基本的な流れは以上です。

おまけ:Google open idエラー直すのに半日

一通り設定を終え、いざrunserverをしてログインを試みると、
AttributeError: module 'social_core.backends.google' has no attribute 'GoogleOpenId'
に引っかかってしまいました。

私はあまり英語が読めないので、解読に時間がかかり途方に暮れていました。
調べてみると、social_core.backends.googleにはもともと、GoogleOpenIdという属性があったようなのですが、以下のサイトによれば、どうやらバージョンアップに伴って廃止されたようです。

Also, note that social_core.backends.google.GoogleOpenId has been deprecated.

バージョンを気にせずに過去の記事をそのままコピペしてsettings.pyに余計な2行書いてたのがダメだったみたいです。
塩は初心者なので、コピペしか能がないのですが、今回の事で英語をもっと学ぼうと思いました。
以下、修正点を挙げています。

エラーになったコード

settings.py
AUTHENTICATION_BACKENDS = (
  'social_core.backends.open_id.OpenIdAuth',  
  'social_core.backends.google.GoogleOpenId',  
 'social_core.backends.google.GoogleOAuth2',  
 'django.contrib.auth.backends.ModelBackend',
)

OKコード

settings.py
AUTHENTICATION_BACKENDS = (
 'social_core.backends.google.GoogleOAuth2', 
 'django.contrib.auth.backends.ModelBackend',
)

おまけ:ログアウト後のページがなんか変!

実装していく中で、こんな課題に直面しました。
ローカルでrunserverした状態でログアウトリンクを押すと、謎のDjango管理画面に遷移してしまう…。
これを解消するために、以下を追加しました。

LOGOUT_URLとLOGOUT_REDIRECT_URLです。
LOGOUT_REDIRECT_URLについては、settings.pyに直接、ログアウト後にリダイレクトするページを指定できるようです。私の場合は作成済みのtop画面にリダイレクトしたいので、'top'ですね。

settings.py
LOGOUT_URL = 'logout' #追加
LOGOUT_REDIRECT_URL = 'top' #追加

また、ログイン後になぜかaccounts/profileというURLに遷移してしまっていたので、対症療法的な感じで'accounts/profile'と呼び出したいビューを結びつけておきました。もっと正しい解決方法があると思うのですが、とりあえずこのような感じで落ち着いています。

ログイン後にaccounts/profileに遷移してしまう場合については、settings.pyにリダイレクト先を追記することで対応できました。今回はtopページに飛びたいので'top'を指定します。

settings.py
LOGIN_REDIRECT_URL = 'top' #追加

以上になリます。

Discussion