[PYTHON] [Studiennotiz] OAuth2-Integration zwischen Django-Projekten

Einführung

Dieser Artikel war Sehr nützlicher Artikel, um den Ablauf der OAuth2-Integration zwischen zwei in der lokalen Umgebung erstellten Django-Projekten zu untersuchen. Dies ist eine Zusammenfassung mit einigen Notizen, die für mich hinzugefügt wurden und sich auf projects-oauth2 /) beziehen. Mit Ausnahme von Änderungen im Schreibstil von URLconf und django.contrib.auth aufgrund des Versions-Upgrades von django wird der Originalartikel fast umgeleitet.

Ziel

Erstellen Sie zwei Django-Projekte (test_provider, test_consumer) in Ihrer lokalen Umgebung und rufen Sie mit OAuth2 (Dummy-) Profilinformationen ab

Projektübersicht

Quellcode

test_provider

test_consumer

Verzeichnisaufbau

test-oauth
│
├── test_consumer
│   ├── templates
|   |   └──index.html
|   |
│   ├── test_consumer
|   |   ├── __init__.py
|   |   ├── settings.py
|   |   ├── urls.py
|   |   └── wsgi.py
|   |
|   ├── testprovider
|   |   ├── __init__.py
|   |   ├── provider.py
|   |   ├── urls.py
|   |   └── wsgi.py
|   |
│   ├── manage.py
│   └── db.sqlite3
├── test_provider
|   ├── templates
|   |   └──registration
|   |      └──login.html
|   |
|   ├── test_provider
|   |   ├── __init__.py
|   |   ├── settings.py
|   |   ├── urls.py
|   |   └── wsgi.py
|   |
|   ├── db.sqlite3
|   └── manage.py
|
├── .gitignore
├── Pipfile
└── Pipfile.lock

Umgebung

Entwicklung des OAuth2-Anbieters

Projekterstellung


mkdir test-oauth
$ cd test-oauth
$ pipenv --python 3.8
$ pipenv install django, django-oauth-toolkit, django-cors-headers
$ pipenv shell

(pipenv)$ django-admin.py startproject test_provider
(pipenv)$ cd test_provider

Bearbeiten Sie test_provider / settings.py

Zu INSTALLED_APPS hinzugefügt

settings.py


INSTALLED_APPS = [
    #hinzufügen
    'oauth2_provider',
    'corsheaders',
]

Zu MIDDLEWARE_CLASSES hinzugefügt

settings.py


MIDDLEWARE = [
    #hinzufügen
    'corsheaders.middleware.CorsMiddleware',
]

Wie in den offiziellen Dokumenten erwähnt, Es scheint, dass Sie es auf der eingebauten Middleware "django.middleware.common.CommonMiddleware" schreiben müssen.

Zum Ende hinzufügen

settings.py


CORS_ORIGIN_ALLOW_ALL = True

Bearbeiten von test_provider / urls.py

test_provider/urls.py



from django.contrib import admin
from django.urls import path, include
from .views import profile_view, top_view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
    path('', top_view),
    path('accounts/', include('django.contrib.auth.urls')),
    path('api/profile/', profile_view, name='profile'),
]

Da ich es schnell erstellen möchte, verwendet die Anmeldefunktion ** django.contrib.auth **, eine integrierte Authentifizierungsfunktion, und löst URL-Muster und -Ansichten vollständig aus (Vorlagen müssen von Ihnen selbst erstellt werden).

Erstellen Sie test_provider / views.py

test_provider/views.py


from django.http import JsonResponse
from oauth2_provider.views.generic import ProtectedResourceView
from django.http import HttpResponse


def top_view(request):
    return HttpResponse("It works!")

class ProfileView(ProtectedResourceView):
    def get(self, request, **kwargs):
        user = request.resource_owner

        return JsonResponse({
            'user_id': user.id,
            'email': user.email,
            'date_joined': user.date_joined,
            'secret_message': 'This is secret message',
        })


profile_view = ProfileView.as_view()

Hier werden eine Ansicht definiert, die einfach die obere Seite anzeigt, und eine Ansicht, die JSON mit Benutzerinformationen zurückgibt.

Registrieren Sie die Oauth-Anwendung auf der Admin-Site

(pipenv)$ python manage.py migrate
(pipenv)$ python manage.py createsuperuser
(pipenv)$ python manage.py runserver

Registrieren Sie die OAuth-Anwendung im Voraus, um die Client-ID und das Client-Geheimnis der Anwendung zu erhalten. Registrieren Sie zu diesem Zeitpunkt auch die Rückruf-URL der Webanwendung. Melden Sie sich einmal bei der Admin-Site (http://127.0.0.1:8000/admin/) an, um auf die Einstellungsseite des Anbieters zuzugreifen. http://127.0.0.1:8000/o/applications/ Öffnen Sie die OAuth-App und fügen Sie sie hinzu.

Elemente einstellen Wert einstellen
Name etwas
client Type Confidential
Authorization grant type Authorization code
Redirect urls: http://localhost:8001/accounts/testprovider/login/callback/
(Das gleiche wie oben) http://127.0.0.1:8001/accounts/testprovider/login/callback/

Erstellen Sie einen Testbenutzer

Erstellen Sie einen Benutzer, der bei der Anmeldung bei OAuth verwendet werden soll. http://127.0.0.1:8000/admin/auth/user/

Erstellen einer OAuth2-Verbrauchertest-App

Erstellen Sie eine App, die Authentifizierung und Autorisierung von test_provider anfordert.

Projekterstellung

(pipenv)$ cd test-oauth

(pipenv)$ django-admin.py startproject test_consumer

(pipenv)$ cd test_consumer

Bearbeiten Sie test_consumer / settings.py

Zu INSTALLED_APP hinzugefügt

test_consumer/settings.py


INSTALLED_APPS = [
    #hinzufügen
   'django.contrib.sites',
   'test_consumer',
   'allauth',
   'allauth.account',
   'testprovider',
]

Zum Ende hinzufügen

test_consumer/settings.py


AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'allauth.account.auth_backends.AuthenticationBackend',
)

SITE_ID = 1
SESSION_COOKIE_NAME = 'test-consumer-session-id'
#Nach dem Login zur obersten Seite umleiten
LOGIN_REDIRECT_URL = '/'

Geben Sie das Übergangsziel nach der Authentifizierung mit ** LOGIN_REDIRECT_URL ** an.

Bearbeiten von test_consumer / urls.py

test_consumer/urls.py



from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', TemplateView.as_view(template_name='index.html')),
    path('accounts/', include('allauth.urls')),
]

Vorlage erstellen

(pipenv)$ mkdir test_consumer/templates

index.html


<!DOCTYPE html>
{% load socialaccount %}
{% load account %}

<html>
<head>
    <meta charset="utf-8">
    <title>testprovider</title>
</head>
<body>
{% if user.is_authenticated %}
Herzlich willkommen{% user_display user %}Herr.<br />
  {% for sa in user.socialaccount_set.all %}
    {{ sa.extra_data }}<br />
  {% endfor %}
{% else %}
  <a href="{% provider_login_url "testprovider" %}">
Melden Sie sich mit dem Testanbieter an
  </a>
{% endif %}
</body>
</html>

Verwenden Sie zum Überprüfen des Vorgangs ** {% if user.is_authenticated%} **, um den Anmeldelink im Status "Abgemeldet" und die Benutzerinformationen im Status "Abgemeldet" anzuzeigen.

Erstellen eines Testprovider-Adapters

Vererbung der "Provider" -Klasse unter Bezugnahme auf Implementierung von django-allauth für die Anmeldung für verschiedene Anbieter Implementieren Sie den Testprovider-Adapter. [Zusatz] Anbieter, die nicht zu "Anbietern" von "django-allauth" gehören, können diesen Bereich neu schreiben, um eine selbst erstellte soziale Anmeldefunktion zu erstellen. ** **.

testprovider/provider.py


from allauth.socialaccount import providers
from allauth.socialaccount.providers.base import ProviderAccount
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider

class TestAccount(ProviderAccount):

    def to_str(self):
        dflt = super(TestAccount, self).to_str()
        return self.account.extra_data.get('name', dflt)

class TestProvider(OAuth2Provider):
    id = 'testprovider'
    name = 'Test Provider'
    account_class = TestAccount

    def get_default_scope(self):
        return ['read', 'write']

    def get_site(self):
        settings = self.get_settings()
        return settings.get('SITE', 'testprovider')

    def extract_uid(self, data):
        uid = str(data['user_id'])
        return uid

    def extract_common_fields(self, data):
        return dict(username=data.get('email', 'no name'))

providers.registry.register(TestProvider)

testprovider/urls.py


from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns
from .provider import TestProvider

urlpatterns = default_urlpatterns(TestProvider)

testprovider/views.py



import requests

from allauth.socialaccount.providers.oauth2.views import (OAuth2Adapter,
                                                          OAuth2LoginView,
                                                          OAuth2CallbackView)
from allauth.socialaccount.providers import registry

from .provider import TestProvider

from django.conf import settings

server_url_prefix = getattr(
    settings, 'TEST_PROVIDER_URL_PREFIX',
    'http://127.0.0.1:8000')

class TestOAuth2Adapter(OAuth2Adapter):
    provider_id = TestProvider.id
    access_token_url = server_url_prefix + '/o/token/'
    authorize_url = server_url_prefix + '/o/authorize/'
    profile_url = server_url_prefix + '/api/profile/'

    def complete_login(self, request, app, token, **kwargs):
        provider = registry.by_id(app.provider)
        resp = requests.get(self.profile_url,
                            params={'access_token': token.token})

        extra_data = resp.json()
        return self.get_provider().sociallogin_from_response(
            request, extra_data)

oauth2_login = OAuth2LoginView.adapter_view(TestOAuth2Adapter)
oauth2_callback = OAuth2CallbackView.adapter_view(TestOAuth2Adapter)

Erstdatenregistrierung auf der Admin-Site

(pipenv)$ python manage.py migrate
(pipenv)$ python manage.py createsuperuser
(pipenv)$ python manage.py runserver 8001

http://127.0.0.1:8001/admin Klicken Sie auf + Hinzufügen in [SOZIALKONTEN]> [Soziale Anwendungen] Legen Sie die "Client-ID" und das "Client-Geheimnis" der auf der Seite test_provider registrierten Anwendung fest

Elemente einstellen Wert einstellen
Provider Test Provider
Name Test Provider
Client id Client-ID früher erstellt
Secret key Geheimschlüssel, den ich früher gemacht habe
Key Himmel
Sites example.Wählen Sie com

Funktionsprüfung

http://127.0.0.1:8001 Melden Sie sich als Testbenutzer an, den Sie zuvor mit einem anderen Browser als dem mit test_provider angemeldeten Browser erstellt haben.

[Mit Testanbieter anmelden]> "Autorisieren"

Wenn die ID-Verknüpfung erfolgreich ist, ist das Ziel das Umleitungsziel http://127.0.0.1:8001 nach erfolgreicher Anmeldung, das in ** test_consumer / settings.py ** festgelegt wurde, und die Benutzerinformationen, die im Abmeldestatus nicht angezeigt wurden, werden angezeigt. Es soll angezeigt werden.

Am Ende

Als nächstes werde ich diesen Inhalt entwickeln, um eine soziale Anmeldefunktion für Dienstanbieter zu erstellen, die nicht von ** django-allauth ** bereitgestellt wird.

Recommended Posts

[Studiennotiz] OAuth2-Integration zwischen Django-Projekten
Django Lernnotiz
LPIC101 Studiennotiz
Django Tutorial Memo
Heroku-Einsatznotiz (Django)
Twitter OAuth mit Django
Django Memo # 1 von Grund auf neu
Job Scheduling @ Study Memo
Shell script @ study memo
[Memo] Django-Entwicklungsumgebung