2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

この記事誰得? 私しか得しないニッチな技術で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

Django、django-allauthで、Facebookログインの設定をする(WEBブラウザ&スマフォ)

Last updated at Posted at 2024-07-02

概要

  • Djangoフレームワーク+django-allauthパッケージで、Facebookログインを実装します

準備

settings.py の設定

  • 基本は 公式ドキュメント の通りです

  • allauth、facebookログインの設定をします

  • INSTALLED_APPS"django.contrib.sites", が必要ですが、公式ドキュメントには書かれていません

--- a/dj_fb_login/dj_fb_login/settings.py
+++ b/dj_fb_login/dj_fb_login/settings.py
@@ -37,6 +37,13 @@ INSTALLED_APPS = [
     "django.contrib.sessions",
     "django.contrib.messages",
     "django.contrib.staticfiles",
+    # sites
+    "django.contrib.sites",
+    # django-allauth
+    'allauth',
+    'allauth.account',
+    # Optional -- requires install using `django-allauth[socialaccount]`.
+    'allauth.socialaccount',
+    # ... include the providers you want to enable:
+    'allauth.socialaccount.providers.facebook',
 ]
 
 MIDDLEWARE = [
@@ -47,6 +54,8 @@ MIDDLEWARE = [
     "django.contrib.auth.middleware.AuthenticationMiddleware",
     "django.contrib.messages.middleware.MessageMiddleware",
     "django.middleware.clickjacking.XFrameOptionsMiddleware",
+    # Add the account middleware:
+    "allauth.account.middleware.AccountMiddleware",
 ]

 ROOT_URLCONF = "dj_fb_login.urls"
@@ -62,11 +71,20 @@ TEMPLATES = [
                 "django.template.context_processors.request",
                 "django.contrib.auth.context_processors.auth",
                 "django.contrib.messages.context_processors.messages",
+                # `allauth` needs this from django
+                'django.template.context_processors.request',
             ],
         },
     },
 ]

+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 email
+    'allauth.account.auth_backends.AuthenticationBackend',
+]
+
 WSGI_APPLICATION = "dj_fb_login.wsgi.application"


@@ -125,3 +143,31 @@ STATIC_URL = "static/"
 # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field

 DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
+
+
+# Site Setting for Login with Facebook.
+SITE_ID = 1
+
+# Provider specific settings
+SOCIALACCOUNT_PROVIDERS = {
+    "facebook": {
+        "METHOD": "oauth2",
+        "SDK_URL": "//connect.facebook.net/{locale}/sdk.js",
+        "SCOPE": ["email", "public_profile"],
+        "AUTH_PARAMS": {"auth_type": "reauthenticate"},
+        "INIT_PARAMS": {"cookie": True},
+        "FIELDS": [
+            "id",
+            "email",
+            "name",
+            "first_name",
+            "last_name",
+            "gender",
+        ],
+        "EXCHANGE_TOKEN": True,
+        "VERIFIED_EMAIL": False,
+        "VERSION": "v7.0",
+        #
+        "LOCALE_FUNC": lambda request: "ja_JP",
+    }
+}

データベースにallauthで必要なテーブルを作成

  • Dockerコンテナ内で、データベースのマイグレーションを行います
docker exec -it django-fb-login-web-1 python manage.py migrate

Facebookアプリの審査に必要な仕組みの導入

  • 開発者ページの「 App Review - Content 」によると、プライバシーポリシーのページを作る必要があります
  • 同じく開発者ページの「 Developer Data Security Best Practices 」によると、利用者が退会したい場合の処理(アカウントの削除)ができる必要があるようです(利用者の住む国や地域によるかも知れません)

Facebookでアプリを作成

サイトURLの設定

  • https://localhost:5005/admin を開いて、ログインして管理画面を表示します
  • 「SITES」-「Sites」をクリックして、example.comlocalhost に変更します
    • 実際のドメインがある場合は、読み替えてください(以下、同じ)

データベースにFacebook上のアプリを設定

  • https://localhost:5005/admin を開いて、ログインして管理画面を表示します

  • 「SOCIAL ACCOUNTS」-「Social applications」の「Add」をクリックします

  • 以下のように設定し、「Save」をクリックします

    • Provider: Facebook
    • Name: アプリ名
    • Client ID: 上記で作成した App ID
    • Secret key: 上記で作成した App secret
    • Sites: Available sites から上記で作成したサイト localhost を選択して、右向き矢印ボタンを押して Chosen sites に移す
      • (上記はDBの socialaccount_socialapp に入ります)
    • Saveボタンで保存します
  • 以下のコマンドで、fixture用のyamlファイルを出力できます。ただし、アプリのID(client_id)やsecertが含まれてしまうので、ご注意ください。頻繁に再設定しない場合は、手動で上記の手順を行うのがよさそうです。

    • python manage.py dumpdata socialaccount.SocialApp --output socialapp_data.yml --format yaml
- model: socialaccount.socialapp
  pk: 1
  fields:
    provider: facebook
    provider_id: facebook
    name: Myapp01
    client_id: '1234567890'
    secret: '9999999999'
    key: ''
    settings: {}
    sites:
    - 1

urlルーティングの追加

  • 今回作成したプロジェクト内の urls.py に、allauthを使うパスを追加します
    • すでに accounts/ が定義されている場合は、その下に追加します
--- a/dj_fb_login/dj_fb_login/urls.py
+++ b/dj_fb_login/dj_fb_login/urls.py
@@ -15,8 +15,9 @@ Including another URLconf
     2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
 """
 from django.contrib import admin
-from django.urls import path
+from django.urls import include, path

 urlpatterns = [
     path("admin/", admin.site.urls),
+    path('accounts/', include('allauth.urls')),
+    path("accounts/", include("allauth.socialaccount.urls")),
 ]

ブラウザで表示確認

  • http://localhost:5005/accounts/login/ を開きます
    • adminで入ったままの場合は、http://localhost:5005/accounts/logout/ を開いて、ログアウトします
  • 下側にある「Or use a third-party」の「Facebook」リンクをクリックします
  • 下側にある「Continue」ボタンをクリックします
  • Facebookの認証画面が表示されます
    • アプリIDやApp secretが間違っていると、エラーが出ます
    • Facebookのアプリ側の設定が間違っていると「アクティブでないアプリです」「現在このアプリにアクセスできません。アプリの開発者は問題を認識しています。アプリが再びアクティブになった時点でログインできるようになります。」と表示されます

テンプレートの編集

既存のテンプレートに「Login with Facebook」ボタンを追加する

以下を追加

{% load socialaccount %}

以下を追加

<div>
  <a href="{% provider_login_url 'facebook' %}" class="btn-facebook">Signup with Facebook</a>
</div>

以下のスタイルシートを追加して、テンプレートから読み込み

.btn-facebook {
    display: inline-block;
    background-color: #1877F2;

    color: white;
    padding: 10px 20px;

    text-align: center;
    text-decoration: none;

    border-radius: 5px;
}
.btn-facebook:hover {
    background-color: #145dbf;
    color: white;
}

Facebookログイン用のページを新規作成

  • templates/socialaccount/login.html というファイルを新規作成します

  • 以下のように記述します

    • 元の GitHubの該当リポジトリ からコピペして、postするボタンの部分を書き換えています
      • 元は標準の灰色の小さいボタンだったため
{% extends "base.html" %}  <!-- この辺は既存のテンプレートと合わせてください -->
{% load i18n %}
{% load allauth %}
{% load socialaccount %}
{% load static %}
{% block head_content %}  <!-- この辺は既存のテンプレートと合わせてください -->
  <link href="{% static 'css/btn_facebook.css' %}" rel="stylesheet">
{% endblock %}

{% block head_title %}
    {% trans "Sign In" %}
{% endblock head_title %}
{% block content %}
    {% if process == "connect" %}
        {% element h1 %}
            {% blocktrans with provider.name as provider %}Connect {{ provider }}{% endblocktrans %}
        {% endelement %}
        {% element p %}
            {% blocktrans with provider.name as provider %}You are about to connect a new third-party account from {{ provider }}.{% endblocktrans %}
        {% endelement %}
    {% else %}
        {% element h1 %}
            {% blocktrans with provider.name as provider %}Sign In Via {{ provider }}{% endblocktrans %}
        {% endelement %}
        {% element p %}
            {% blocktrans with provider.name as provider %}You are about to sign in using a third-party account from {{ provider }}.{% endblocktrans %}
        {% endelement %}
    {% endif %}
    {% element form method="post" no_visible_fields=True %}
        {% slot actions %}
            {% csrf_token %}
            <button type="submit" class="btn-facebook">
                {% trans "Login with Facebook" %}
            </button>
        {% endslot %}
    {% endelement %}
{% endblock content %}

スマフォでFacebookアプリを起動するように修正

  • スマフォからのアクセス時にFacebookアプリを自動で起動するには、上記の{% endblock content %}の直前に、以下のコードを追加します
    • IDの 123456789012345 は、書き換えてください(3か所とも)
    • Android版のアプリを起動する際は、fb:// で起動しなかったので、intent:// を使っています
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var userAgent = navigator.userAgent || navigator.vendor || window.opera;
            var fbAppUrl = "intent://page/123456789012345#Intent;package=com.facebook.katana;scheme=fb;end";
            var fbWebUrl = "https://www.facebook.com/123456789012345";

            function openFacebookApp(url) {
                var start = Date.now();
                var timeout = setTimeout(function() {
                    if (Date.now() - start < 2000) {
                        window.location.href = fbWebUrl;
                    }
                }, 1500);

                window.location.href = url;
                window.addEventListener('blur', function() {
                    clearTimeout(timeout);
                });
            }

            if (/android/i.test(userAgent)) {
                // Androidデバイスの場合
                openFacebookApp(fbAppUrl);
            } else if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
                // iOSデバイスの場合
                window.location.href = "fb://profile/123456789012345";
            }
        });
    </script>
2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?