はじめに
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.pyのINSTALLED_APP
にsocial_django
を追加
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.pyにAUTHENTICATION_BACKENDS
を定義して、使いたい認証バックエンドを追加します。
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.pyのTEMPLATES
にcontext_processorを追加します。
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_URL
とLOGIN_REDIRECT_URL
を指定します。
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ファイルを作成していきます
この辺の詳しい説明は省きます
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
{% extends 'base.html' %}
{% block content %}
<h1>Hello World!!</h1>
<a href="{% url 'login' %}">ログイン</a>
{% endblock %}
{% 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
で認証済みか確認しています
次に、ログインページとログアウトページを作成しますが、LoginView
とLogoutView
の仕様に沿って、templatesにregistrationディレクトリを作成して、その中に login.html と logged_out.htmlファイルを作成します。
以下、templatesの構造
templates/
┣ registration/
┃ ┣ login.html
┃ ┗ logged_out.html
┣ base.html
┣ home.html
┗ toppage.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>
この部分が認証画面に飛ばしてくれます。
{% extends 'base.html' %}
{% block content %}
<h2>ログアウトしました</h2>
<ul>
<li><a href="{% url 'landing' %}">ランディングページへ</a></li>
<li><a href="{% url 'login' %}">ログインページへ</a></li>
</ul>
{% endblock %}
これで準備ができましたので、実際に動かしてみましょう
動作確認
意図した挙動してますね!
##終わりに
social-auth-app-djangoを使うとこんなにも簡単にログイン機能が作れるんですね!
ちょっとびっくりしています。
この記事が誰かのためになれたら幸いです!
ここに書いてある事が絶対正しい!!というわけではないので、間違いなどのご指摘がございましたらコメントお願いします!🙇♂️