7
6

More than 1 year has passed since last update.

[Django] social-auth-app-djangoを用いてGoogle OAuth2ログイン認証をする

Last updated at Posted at 2021-02-21

はじめに

Googleアカウントを使ったログイン機能がほしかったので作りました。
social-auth-app-djangoを使うと簡単に作れるみたいなので、ありがたく使わせていただきます!

今回はGoogleアカウントを使ったログイン機能を作ることに焦点を当てているため、RESTなどはあまり意識していません。

前知識

social-auth-app-djangoとは

  • DjangoでOAuth認証を行う時に使うサードパーティ製のパッケージ
  • Google, Twitter, Facebook などのプロバイダーのアカウントを使って認証処理ができる

環境

  • python 3.7.4
  • django 3.0.3

作業開始

social-auth-app-djangoをインストール

$ pip install social-auth-app-django

アプリケーションの登録

settings.pyINSTALLED_APPsocial_djangoを追加

setting.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'social_django',# これを追加した
]

デフォルトでDjango ORMが使用されるため、もしMongo ORMを使いたい時は別の処理が必要です。
Mongo ORM使いたい方へ 参考

DB

social_djangoをINSTALLED_APPSに登録したら、migrateを行い、DBを同期させ、必要なモデルを構築します。

$ ./manage.py migrate

認証バックエンドの登録

次に、認証バックエンドを登録していきます。
settings.pyAUTHENTICATION_BACKENDSを定義して、使いたい認証バックエンドを追加します。

settings.py
AUTHENTICATION_BACKENDS = (
    'social_core.backends.open_id.OpenIdAuth',
    'social_core.backends.google.GoogleOAuth2',
    'social_core.backends.google.GoogleOAuth',
    'social_core.backends.twitter.TwitterOAuth',
    'social_core.backends.yahoo.YahooOpenId',
    'django.contrib.auth.backends.ModelBackend',
)

最後の行にあるdjango.contrib.auth.backends.ModelBackendを忘れるとdjango.contrib.authを使った認証がうまくできなくなります。ログインできない時はここが抜けてないかチェックしてみてください。

このパートは、認証に使いたいプロバイダーに合わせて認証バックエンドを登録する必要があります。
サポートされているプロバイダー

Context_Processorsを登録

settings.pyTEMPLATESにcontext_processorを追加します。

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', # 追加
            ],
        },
    },
]

backends context processer の中には以下の3つの情報が辞書型として含まれています。

  • associated : 現在ログインしているユーザーに関連するUserSocialAuthのインスタンスのリスト(ユーザーがいない場合は空)
  • not_associated : 現在ログインしているユーザーに関連付けされていない利用可能なバックエンド名のリスト
  • backends : 利用可能なすべてのバックエンド名のリスト

URLの設定

トップページ(誰でも見れる) → ログインページ → ホームページ(ログインしないと見れない)
の流れでアクセスできるようなURLを作成していきます

from django.contrib import admin
from django.urls import path
from django.urls.conf import include
from django.contrib.auth.views import LoginView, LogoutView
from . import views

urlpatterns = [
    path('', views.toppage, name='toppage'),
    path('admin/', admin.site.urls),
    path('auth/', include('social_django.urls', namespace='social')), # これが重要
    path('login/', LoginView.as_view(), name='login'),
    path('logout/', LogoutView.as_view(), name='logout'),
    path('home/', views.home, name='home'),
]

ログインしたらログアウトできないとお辛いので、ログアウトもできるようにしときましょう。
最後に、LOGIN_URLLOGIN_REDIRECT_URLを指定します。

settings.py
LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'home'

クライアントIDとシークレットキーを取得

Google API Consolseに移動し、新しいプロジェクトを作成し、認証情報を作成します。
その際に

  • 承認済みの JavaScript 生成元
  • 承認済みのリダイレクト URI

それぞれ聞かれるので

承認済みの JavaScript 生成元を

http://localhost:8000

認証済みリダイレクトURIを

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

と設定して、保存してください。
今回はローカルで動かしているので、これで問題ないのですが
もし、本番環境で使う場合はドメインの部分を変更してください。

クライアントIDとシークレットキーを取得できたら、settings.py
にそれぞれ記載します。

SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = 'hogehoge' # クライアントID
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET 'hugahuga' # シークレットキー

ベタガキしたくない人は環境変数に持たせるといいかもしれません

views.pyの編集

from django.contrib.auth.decorators import login_required
from django.shortcuts import render


def toppage(request):
    return render(request, 'toppage.html')


@login_required
def home(request):
    return render(request, 'home.html')

htmlをレンダリングするシンプルな関数ですね

Templateの作成

templates内にhtmlファイルを作成していきます
この辺の詳しい説明は省きます

base.html
<!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="UTF-8">
  </head>
  <body>
      {% block content %}
      {% endblock %}
  </body>
</html>
toppage.html
{% extends 'base.html' %}

{% block content %}
  <h1>Hello World!!</h1>
  <a href="{% url 'login' %}">ログイン</a>
{% endblock %}
home.html
{% extends 'base.html' %}

{% block content %}
{% if user.is_authenticated %}
  <h1>ログイン成功!!</h1>
  <h2>{{ user.username }}がログイン中</h2>
  <p>is_authenticated : {{ user.is_authenticated }}</p>
  <p>user_name : {{ user.username }}</p>
  <p>backends: {{ backends }}</p>
{% endif %}
<a href="{% url 'logout' %}">ログアウト</a>

{% endblock %}

home.html時点で認証は成功していますが、念のためis_authenticatedで認証済みか確認しています

次に、ログインページとログアウトページを作成しますが、LoginViewLogoutViewの仕様に沿って、templatesregistrationディレクトリを作成して、その中に login.htmllogged_out.htmlファイルを作成します。

以下、templatesの構造

templates/
┣ registration/
┃ ┣ login.html
┃ ┗ logged_out.html
┣ base.html
┣ home.html
┗ toppage.html

login.html
{% extends 'base.html' %}

{% block content %}
  <h2>ログインに使用するサービスを選択してください
    <ul>
        <li><a href="{% url 'social:begin' 'google-oauth2' %}">Googleアカウントでログイン</a></li>
    </ul>
{% endblock %}
<li><a href="{% url 'social:begin' 'google-oauth2' %}">Googleアカウントでログイン</a></li>

この部分が認証画面に飛ばしてくれます。

logged_out.html
{% extends 'base.html' %}

{% block content %}
  <h2>ログアウトしました</h2>
  <ul>
      <li><a href="{% url 'landing' %}">ランディングページへ</a></li>
      <li><a href="{% url 'login' %}">ログインページへ</a></li>
  </ul>
{% endblock %}

これで準備ができましたので、実際に動かしてみましょう

動作確認

トップページ
スクリーンショット 2021-02-21 13.48.29.png

ログインページ
スクリーンショット 2021-02-21 13.48.34.png

ホームページ
IMG_0216.png

ログアウトページ
スクリーンショット 2021-02-21 13.50.20.png

意図した挙動してますね!

##終わりに
social-auth-app-djangoを使うとこんなにも簡単にログイン機能が作れるんですね!
ちょっとびっくりしています。
この記事が誰かのためになれたら幸いです!

ここに書いてある事が絶対正しい!!というわけではないので、間違いなどのご指摘がございましたらコメントお願いします!🙇‍♂️

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6