[PYTHON] Créez une API d'intégration sociale pour les applications smartphone avec Django

Contexte

Il y a des moments où vous souhaitez utiliser OAuth pour lier votre propre compte de service à un compte de service externe tel que Facebook ou Twitter. Pour Python3, vous pouvez facilement ajouter un écran de liaison de compte externe pour les services Web en utilisant python-social-auth. Cependant, si vous souhaitez faire de même avec une application pour smartphone, vous devez fournir une fonction de lien avec l'API, donc une note sur la façon de la gérer.

Objectif

Cette fois, nous assumons la fonction de prise de contrôle de l'utilisateur dans l'application pour smartphone. Les services externes que je souhaite utiliser sont Facebook et Twitter. Les deux fonctions suivantes sont implémentées.

  1. API pour lier un compte externe à un utilisateur Django existant
  2. API pour obtenir les informations utilisateur Django associées à partir des informations de compte externe

[Social Auth with Django REST Framework] (https://yeti.co/blog/social-auth-with-django-rest-framework/)

environnement

Python 3.4.3 Django 1.8

Flux d'authentification

Le flux de traitement d'authentification est supposé être le suivant en utilisant OAuth.

  1. Obtenez un jeton OAuth pour l'authentification à l'aide de divers SDK dans l'application pour smartphone.
  1. Envoyez le jeton OAuth obtenu en 1. de l'application pour smartphone à votre propre service
  1. Obtenez un ID utilisateur auprès d'un service externe à l'aide du jeton OAuth reçu par votre propre service
  1. Si l'ID utilisateur peut être obtenu en 3., effectuez le traitement nécessaire (comme la liaison des informations utilisateur) et renvoyez le résultat du traitement à l'application pour smartphone.

Détails d'implémentation

Installation de python-social-auth

python


$ pip install python-social-auth

Paramètres de python-social-auth

settings.py


INSTALLED_APPS = (
    ...
    'social.apps.django_app.default',
    ...
)

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    'social.apps.django_app.context_processors.backends',
    'social.apps.django_app.context_processors.login_redirect',
    ...
)

AUTHENTICATION_BACKENDS = (
   'social.backends.facebook.FacebookOAuth2',
   'social.backends.twitter.TwitterOAuth',
   'django.contrib.auth.backends.ModelBackend',
)

SOCIAL_AUTH_PIPELINE = (
    'social.pipeline.social_auth.social_details',
    'social.pipeline.social_auth.social_uid',
    'social.pipeline.social_auth.auth_allowed',
    'social.pipeline.social_auth.social_user',
    #Supprimez l'utilisateur afin qu'il ne soit pas créé lors de la vérification des informations d'identification
    #'social.pipeline.user.create_user',
    'social.pipeline.social_auth.associate_user',
    'social.pipeline.social_auth.load_extra_data',
    'social.pipeline.user.user_details',
)

SOCIAL_AUTH_TWITTER_KEY = "MY_TWITTER_APP_KEY "
SOCIAL_AUTH_TWITTER_SECRET = "MY_TWITTER_APP_SECRET"

SOCIAL_AUTH_FACEBOOK_KEY = "MY_FACEBOOK_APP_ID"
SOCIAL_AUTH_FACEBOOK_SECRET = "MY_FACEBOOK_APP_SECRET"

Créer une table pour les informations d'identification

python


$ ./manage.py migrate

Paramètres d'URL à l'échelle du projet

myproject/urls.py


from django.conf.urls import url

urlpatterns = [
    ...
    url('', include('social.apps.django_app.urls', namespace='social'))
    ...
]

Paramètre d'URL de l'application pour laquelle vous souhaitez utiliser la fonction de liaison

myapp/urls.py


from django.conf.urls import url
from . import views

urlpatterns = [
	# 1.API pour lier un compte externe à un utilisateur qui existe déjà
    url(r'api/associate/(?P<backend>[^/]+)/$', views.associate_account, name='associate_account'),
	# 2.API pour obtenir des informations utilisateur liées à partir d'informations de compte externe
    url(r'api/auth/(?P<backend>[^/]+)/$', views.auth_account, name='auth_account'),
]

Vue de l'application pour laquelle vous souhaitez utiliser la fonction de liaison

myapp/views.py


from django.contrib.auth import login

from rest_framework import status
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import api_view, permission_classes

from social.backends.oauth import BaseOAuth1, BaseOAuth2
from social.apps.django_app.utils import psa

# 1.API pour lier un compte externe à un utilisateur qui existe déjà

@api_view(('POST',))
@permission_classes((IsAuthenticated,))
@psa('social:complete')
def associate_account(request, backend):
    backend = request.backend
    token = _make_token(request, backend)
    #L'utilisateur est renvoyé uniquement lorsque l'authentification avec OAuth est réussie
    user = backend.do_auth(token, user=request.user)
    if user:
        login(request, user)
        return Response({'success': True})
    else:
        return Response({"errors": "Error with social authentication"},
                            status=status.HTTP_400_BAD_REQUEST)

# 2.API pour obtenir des informations utilisateur liées à partir d'informations de compte externe

@api_view(('POST',))
@psa('social:complete')
def auth_account(request, backend):
    backend = request.backend
    token = _make_token(request, backend)
    #L'utilisateur est renvoyé uniquement lorsque l'authentification avec OAuth est réussie et qu'un utilisateur est associé à ces informations.
    user = backend.do_auth(token)
    if user:
        return Response({'id': user.id, 'username': user.username})
    else:
        return Response({"errors": "User Not Found"},
                            status=status.HTTP_404_NOT_FOUND)

#La forme du jeton utilisé est différente entre OAuth1 et OAuth2

def _make_token(request, backend):
    if isinstance(backend, BaseOAuth1):
        token = {
            'oauth_token': request.data.get('access_token'),
            'oauth_token_secret': request.data.get('access_token_secret'),
        }
    elif isinstance(backend, BaseOAuth2):
        token = request.data.get('access_token')
    return token

Contrôle de fonctionnement

Coopération avec Twitter

Préparation

  1. Préparez access_token et access_token_secret (d'une certaine manière) pour les utilisateurs qui travaillent avec votre propre application Twitter.
  2. Connectez-vous à l'écran de gestion de votre propre service avec un navigateur.

Comment vérifier la fonction de liaison de service externe

Accédez à l'URL (ex. Http: // myserver / myapp / api / associé / twitter /) avec associé_account défini avec un navigateur.

Django_REST_framework.png

Comme indiqué dans l'écran ci-dessus, entrez access_token et access_token_secret au format json dans le contenu, puis appuyez sur [POST].

{
   "access_token": "my_access_token",
   "access_token_secret": "my_access_token_secret"
}

Si {" success ": true} est renvoyé, l'authentification est réussie.

Django_REST_framework.png

Comment vérifier la fonction d'authentification du service externe

Accédez à l'URL (ex. Http: // myserver / myapp / api / auth / twitter /) pour laquelle auth_account est défini avec un navigateur, et effectuez la même procédure que dans la section précédente.

Succès si l'ID de l'utilisateur qui s'est lié précédemment est renvoyé

Django_REST_framework.png

Pour Facebook

Cela peut être confirmé par presque la même procédure que Twitter, mais les deux points suivants sont différents.

  1. Dans la procédure de confirmation ci-dessus, changez l'endroit où il est «twitter» en «facebook».
  2. La seule information json à envoyer est ʻaccess_token. (OAuth2 n'a pas ʻaccess_token_secret)

Impressions

python-social-auth Pratique! J'ai pu écrire le code requis pour l'authentification en quelques lignes seulement!

Cependant, cette implémentation semble avoir finalement été réalisée en rassemblant diverses informations anglaises dispersées, et j'ai eu l'impression que Python a peu d'informations en japonais.

référence

Je veux me connecter sur Twitter ou Facebook avec Python 3.4 et Django 1.6.5-Today's Hack http://narusemotoki.tumblr.com/post/90525892180/python-34%E3%81%A8django-165%E3%81%A7twitter%E3%82%84facebook%E3%81%A7%E3%81%AE%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%82%92%E3%81%97%E3%81%9F%E3%81%84

omab/python-social-auth https://github.com/omab/python-social-auth

Django Framework — Python Social Auth documentation https://python-social-auth.readthedocs.org/en/latest/configuration/django.html

Pipeline — Python Social Auth documentation https://python-social-auth.readthedocs.org/en/latest/pipeline.html#authentication-pipeline

Use Cases — Python Social Auth documentation http://psa.matiasaguirre.net/docs/use_cases.html#signup-by-oauth-access-token

Twitter OAuth using access_token · Issue #272 · omab/python-social-auth https://github.com/omab/python-social-auth/issues/272

Social Auth with Django REST Framework - Yeti https://yeti.co/blog/social-auth-with-django-rest-framework/

Recommended Posts

Créez une API d'intégration sociale pour les applications smartphone avec Django
Créez un tableau de bord pour les appareils réseau avec Django!
Créer une API avec Django
Créer une page d'accueil avec django
Créez une API Web capable de fournir des images avec Django
(Pour les débutants) Essayez de créer une API Web simple avec Django
Créer un téléchargeur de fichiers avec Django
[Python] Créer un écran pour le code d'état HTTP 403/404/500 avec Django
Créer une API REST pour faire fonctionner dynamodb avec le Framework Django REST
Créez un modèle pour votre planning Django
Créer un LINE BOT avec Minette pour Python
Créez une application Hello World avec un seul fichier avec django
Comment créer une API Rest dans Django
Créez une base de données propre pour les tests avec FastAPI et effectuez le test Unittest de l'API avec pytest
Créer un planning Django
Créez une application Web typée avec le framework Web de Python «Fast API» et TypeScript / Open API - Pile technique pour les applications Web d'apprentissage automatique
Créer une application Todo avec Django REST Framework + Angular
Essayez de créer une application Todo avec le framework Django REST
Créer une application Todo avec Django ③ Créer une page de liste de tâches
Créez une carte thermique de tweet avec l'API Google Maps
Créer une couche pour AWS Lambda Python dans Docker
Créer une application Todo avec Django ⑤ Créer une fonction d'édition de tâches
Créer un environnement django avec docker-compose (MariaDB + Nginx + uWSGI)
Construire un environnement Django pour Win10 (avec espace virtuel)
Les débutants de Django créent des applications simples 3
[Memo] Construire un environnement de développement pour Django + Nuxt.js avec Docker
Les débutants de Django créent des applications simples 1
Recommandation de django, wagtail ~ Pourquoi développer un site web avec python ~
Créer un compte enfant de connect with Stripe en Python
[Django] Créez un modèle adapté au numéro de téléphone / code postal
Créez un Twitter BOT avec le SDK GoogleAppEngine pour Python
Les débutants de Django créent des applications simples 2
Créer un écran de connexion Django
Tornado - Créons une API Web qui renvoie facilement JSON avec JSON
Créer une application Todo avec Django ① Créer un environnement avec Docker
Créer un répertoire avec python
Qiita API Oauth avec Django
Les débutants de Django créent des applications simples 5
Créez un alias pour Route53 vers CloudFront avec l'API AWS
Créez un fichier temporaire avec django sous forme de zip et renvoyez-le
[Python / Django] Créer une API Web qui répond au format JSON
Créez une illusion rayée avec correction gamma pour Python3 et openCV3
Les utilisateurs de Rails essaient de créer un moteur de blog simple avec Django
Comment créer une étiquette (masque) pour la segmentation avec labelme (masque de segmentation sémantique)
[LINE Messaging API] Créez un BOT qui se connecte à quelqu'un avec Python
Créer un environnement pour Django x Apache x mod_wsgi avec Vagrant (Ubuntu 16.04)
J'ai créé un environnement de développement pour Django 3.0 avec Docker, Docker-compose, Poetry
Essayez de créer un article de Qiita avec l'API REST [Préparation environnementale]
Créer un Ubuntu de démarrage USB avec un environnement Python pour l'analyse des données
Créer et renvoyer un fichier CSV CP932 pour Excel avec Chalice
Comment créer une API de machine learning sans serveur avec AWS Lambda
[DynamoDB] [Docker] Créer un environnement de développement pour DynamoDB et Django avec docker-compose
Configurer la connexion sociale avec Django
[AWS] Créer une API avec API Gateway + Lambda
Étapes pour créer un projet Django
Déployer l'application Django avec Docker
Créez un environnement virtuel avec Python!
Django Tips-Créez un site de classement avec Django-
Créer une application Web avec Django