domingo, 31 de diciembre de 2023

21.- Barra de Herramientas de depuración de Django.


Usando la barra de herramientas de depuración de Django.


En este punto, ya estarás familiarizado con la página de depuración de Django. A lo largo de los capítulos anteriores, has visto varias veces la distintiva página de depuración de Django, amarilla y gris. Aparece en cuanto ejecutas el servidor de desarrollo y se detecta algún error en el código.

La página de depuración de Django proporciona información útil para la depuración. Sin embargo, existe una aplicación externa de Django que incluye información de depuración más detallada y puede ser realmente útil durante el desarrollo.

Django Debug Toolbar es una aplicación externa de Django que te permite ver información relevante de depuración sobre el ciclo actual de solicitud y respuesta. La información se divide en múltiples paneles que muestran información diferente, incluyendo datos de solicitud/respuesta (request/response), versiones de paquetes de Python utilizados, tiempo de ejecución, configuraciones, encabezados, consultas SQL, plantillas utilizadas, caché, señales y registro.

Puedes encontrar la documentación para Django Debug Toolbar en https://django-debug-toolbar.readthedocs.io/.


Instalando la barra de depuración de Django.


Instala la barra de depuración via pip usando el siguiente comando:

pip install django-debug-toolbar

Edita el archivo settings.py de tu proyecto y agrega debug_toolbar a la configuración INSTALLED_APPS, de la siguiente manera:
INSTALLED_APPS = [
# ...
'debug_toolbar',
]

En el mismo archivo, agrega la siguiente línea resaltada en negrita a la configuración MIDDLEWARE:

MIDDLEWARE = [
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

La barra de herramientas de depuración de Django se implementa principalmente como middleware. El orden de MIDDLEWARE es importante. DebugToolbarMiddleware debe colocarse antes que cualquier otro middleware, excepto los middleware que codifican el contenido de la respuesta, como GZipMiddleware, que, si está presente, debería ir primero.

Añade las siguientes líneas al final del archivo settings.py de la aplicación principal:

# Django debug toolbar
INTERNAL_IPS = [
'127.0.0.1',
]

La barra de herramientas de depuración de Django solo se mostrará si tu dirección IP coincide con una entrada en la configuración INTERNAL_IPS. Para evitar mostrar información de depuración en producción, Django Debug Toolbar verifica que la configuración DEBUG esté en True.

Edita el archivo urls.py principal de tu proyecto y agrega el siguiente patrón de URL resaltado en negrita a las urlpatterns:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('Proyecto_web_app.urls')),
    path('servicios/', include('Servicios.urls')),
    path('blog/', include('Blog.urls')),
    path('contacto/', include('Contacto.urls')),
    path('sitemap.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
    path('tienda/', include('Tienda.urls')),
    path('carro/', include('Carro.urls')),
    path('cuenta/', include('Autentificacion.urls')),
    path('social-auth/', include('social_django.urls', namespace='social')),
    path('orders/', include('Orders.urls', namespace='orders')),
    path('__debug__/', include('debug_toolbar.urls')),
]


La barra de herramientas de depuración de Django está ahora instalada en tu proyecto. ¡Probémosla!

Ejecuta el servidor de desarrollo con el siguiente comando:

python manage.py runserver

Abre http://127.0.0.1:8000/tienda/ en tu navegador. Ahora deberías ver una barra lateral plegable a la derecha. Debería verse de la siguiente manera:


imagen panel de depuración a la derecha


Si la barra no aparece, comprueba el log de la consola de runserver. Si ves un error de tipo MIME, es muy probable que tu mapa de archivos MIME sea incorrecto o necesite actualizarse.

Puede aplicar la asignación correcta para archivos JavaScript y CSS agregando las siguientes líneas al archivo settings.py:

PracticaDjango/PracticaDjango/settings.py

if DEBUG:
    import mimetypes
    mimetypes.add_type('application/javascript', '.js', True)
    mimetypes.add_type('text/css', '.css', True)


Paneles de la barra de depuración de Django.

La barra de herramientas de depuración de Django cuenta con múltiples paneles que organizan la información de depuración para el ciclo de solicitud(request) y respuesta(response). La barra lateral contiene enlaces a cada panel, y puedes usar la casilla de verificación de cualquier panel para activarlo o desactivarlo. El cambio se aplicará a la siguiente solicitud. Esto es útil cuando no estamos interesados en un panel específico, pero el cálculo agrega demasiada carga a la solicitud.

Haz clic en 'Tiempo' en el menú lateral. Verás el siguiente panel:

Panel, pestaña Tiempo desplegada


Imagen del panel

El panel de Tiempo incluye un temporizador para las diferentes fases del ciclo de solicitud/respuesta. También muestra la CPU, el tiempo transcurrido y el número de cambios de contexto. Si estás utilizando Windows, no podrás ver el panel de Tiempo. En Windows, solo está disponible y se muestra el tiempo total en la barra de herramientas.

Haz clic en 'SQL' en el menú lateral. Verás el siguiente panel:


Panel, SQL desplegado

Aquí puedes ver las diferentes consultas SQL que se han ejecutado. Esta información puede ayudarte a identificar consultas innecesarias, consultas duplicadas que se pueden reutilizar o consultas de larga duración que se pueden optimizar. Según tus hallazgos, puedes mejorar los QuerySets en tus vistas, crear nuevos índices en campos del modelo si es necesario o almacenar en caché información cuando sea necesario.

Haz clic en 'Plantillas' en el menú lateral. Verás el siguiente panel:

Panel plantilla desplegado

Este panel muestra las diferentes plantillas utilizadas al renderizar el contenido, las rutas de las plantillas y el contexto utilizado. También puedes ver los diferentes procesadores de contexto utilizados.

Haz clic en 'Señales' en el menú lateral. Verás el siguiente panel:

Panel, Señales desplegado


En este panel, puedes ver todas las señales registradas en tu proyecto y las funciones receptoras adjuntas a cada señal.

Hemos revisado algunos de los paneles que vienen con la barra de herramientas de depuración de Django. Además de los paneles integrados, puedes encontrar paneles adicionales de terceros que puedes descargar y usar en https://django-debugtoolbar.readthedocs.io/en/latest/panels.html#third-party-panels.

Comandos de la barra de herramientas de depuración de Django

Además de los paneles de depuración de solicitud/respuesta, la barra de herramientas de depuración de Django proporciona un comando de gestión para depurar SQL en llamadas ORM. El comando de gestión debugsqlshell replica el comando de consola de Django, pero muestra declaraciones SQL para consultas realizadas con el ORM de Django.

Abre la consola con el siguiente comando:

python manage.py debugsqlshell

Ejecuta el siguiente código:

Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from Tienda.models import Producto >>> Producto.objects.get(id=1)

Verás la siguiente salida:

SELECT oid, typarray FROM pg_type WHERE typname = 'hstore' [1.06ms] SELECT oid, typarray FROM pg_type WHERE typname = 'citext' [0.50ms] SELECT "Tienda_producto"."id", "Tienda_producto"."nombre", "Tienda_producto"."slug", "Tienda_producto"."categoria_id", "Tienda_producto"."descripcion", "Tienda_producto"."precio", "Tienda_producto"."stock", "Tienda_producto"."imagen", "Tienda_producto"."created", "Tienda_producto"."updated" FROM "Tienda_producto" WHERE "Tienda_producto"."id" = 1 LIMIT 21 [1.69ms] <Producto: NBA2K23>

Puedes utilizar este comando para probar consultas ORM antes de añadirlas a tus vistas. Podrás revisar la declaración SQL resultante y el tiempo de ejecución de cada llamada ORM.

Puedes encontrar el código de este capítulo en este enlace de GITHUB

miércoles, 20 de diciembre de 2023

20.2 Añadiendo autentificación con redes sociales en Django (Facebook, Twitter y Google)

La autenticación social es una característica ampliamente utilizada que permite a los usuarios autenticarse usando su cuenta existente de un proveedor de servicios mediante inicio de sesión único (SSO). El proceso de autenticación les permite a los usuarios iniciar sesión en el sitio utilizando su cuenta existente de servicios sociales como Google. En esta sección, agregaremos autenticación social al sitio utilizando Facebook, Twitter y Google.

Para implementar la autenticación social, utilizaremos el protocolo estándar de la industria OAuth 2.0 para autorización. OAuth significa Open Authorization. OAuth 2.0 es un estándar diseñado para permitir que un sitio web o aplicación acceda a recursos alojados por otras aplicaciones web en nombre de un usuario. Facebook, Twitter y Google utilizan el protocolo OAuth 2.0 para autenticación y autorización.

Python Social Auth es un módulo de Python que simplifica el proceso de agregar autenticación social a tu sitio web. Utilizando este módulo, puedes permitir que tus usuarios inicien sesión en tu sitio web utilizando sus cuentas de otros servicios. Puedes encontrar el código de este módulo en https://github.com/python-social-auth/social-app-django o en https://python-social-auth.readthedocs.io/en/latest/configuration/django.html

Este módulo viene con backends de autenticación para diferentes frameworks de Python, incluyendo Django. Para instalar el paquete de Django desde el repositorio Git del proyecto, abre la consola y ejecuta el siguiente comando dentro de tu entorno virtual:

venv$ pip install social-auth-app-django

Esto instalará Python Social Auth.

Luego, agrega 'social_django' al ajuste INSTALLED_APPS en el archivo settings.py del proyecto de la siguiente manera:

PracticaDjango/PracticaDjango/settings.py

INSTALLED_APPS = [
    # Nuestras aplicaciones
    'Proyecto_web_app.apps.ProyectoWebAppConfig',
    'Servicios.apps.ServiciosConfig',
    'Blog.apps.BlogConfig',
    'Contacto.apps.ContactoConfig',
    'Tienda.apps.TiendaConfig',
    'Carro.apps.CarroConfig',
    'Autentificacion.apps.AutentificacionConfig',
    # Aplicaciones de terceros
    'django_bootstrap5',
    'social_django',
    # Mapa del Sitio

Para que esto funcione necesitamos realizar la migración con:

python manage.py migrate


Python Social Auth incluye backends de autenticación para múltiples servicios. Puedes encontrar la lista con todos los backends disponibles en https://python-social-auth.readthedocs.io/en/latest/backends/index.html#supported-backends.

Vamos a añadir autenticación social a nuestro proyecto, permitiendo que nuestros usuarios se autentiquen con los backends de Facebook, Twitter y Google.

Primero, necesitamos añadir los patrones de URL de inicio de sesión social al proyecto.

Abre el archivo urls.py principal del proyecto, PracticaDjango y añade los patrones de URL de social_django de la siguiente manera. Las nuevas líneas están resaltadas en azul:


PracticaDjango/PracticaDjango/urls.py

#...

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('Proyecto_web_app.urls')),
    path('servicios/', include('Servicios.urls')),
    path('blog/', include('Blog.urls')),
    path('contacto/', include('Contacto.urls')),
    path('sitemap.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
    path('tienda/', include('Tienda.urls')),
    path('carro/', include('Carro.urls')),
    path('cuenta/', include('Autentificacion.urls')),
    path('social-auth/', include('social_django.urls', namespace='social')),
]
urlpatterns+=static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


Nuestra aplicación web actualmente es accesible a través de la IP de localhost 127.0.0.1 o usando el nombre de host localhost. Varios servicios sociales no permitirán redirigir a los usuarios a 127.0.0.1 o localhost después de una autenticación exitosa; esperan un nombre de dominio para la redirección de URL. Primero, necesitamos usar un nombre de dominio para que la autenticación social funcione. Afortunadamente, podemos simular servir nuestro sitio bajo un nombre de dominio en nuestra máquina local.

Localiza el archivo hosts de tu máquina. Si estás usando Linux o macOS, el archivo hosts se encuentra en /etc/hosts. Si estás usando Windows, el archivo hosts está en C:\Windows\System32\Drivers\etc\hosts.

Edita el archivo hosts de tu máquina y añade la siguiente línea:

127.0.0.1 misitio.com

en donde misitio.com es el nombre que quieras para tu nombre de dominio. En mi caso será "unikgame.com"

Esto indicará a tu computadora que el nombre de host misitio.com apunte a tu propia máquina.

Verifiquemos que la asociación del nombre de host funcionó. Ejecuta el servidor de desarrollo usando el siguiente comando desde la consola:

python manage.py runserver

Abre http://misitio.com:8000/account/login/ en tu navegador. Verás el siguiente error:

mensaje de error en la cabecera

Django controla los hosts que pueden servir la aplicación utilizando la configuración ALLOWED_HOSTS. Esta es una medida de seguridad para prevenir ataques de encabezado de host HTTP. Django solo permitirá que los hosts incluidos en esta lista sirvan la aplicación.

Puedes obtener más información sobre la configuración ALLOWED_HOSTS en https://docs.djangoproject.com/en/4.2/ref/settings/#allowed-hosts.

Edita el archivo settings.py del proyecto y modifica la configuración ALLOWED_HOSTS de la siguiente manera. El nuevo código está resaltado en negrita:

PracticaDjango/PracticaDjango/settings.py

#...
ALLOWED_HOSTS = ['misitio.com','localhost','127.0.0.1']


Además del host misitio.com, hemos incluido explícitamente localhost y 127.0.0.1. Esto permite el acceso al sitio a través de localhost y 127.0.0.1, que es el comportamiento predeterminado de Django cuando DEBUG es True y ALLOWED_HOSTS está vacío.

Abre nuevamente http://misitio.com:8000/cuenta/login/ en tu navegador. Ahora deberías ver la página de inicio de sesión del sitio en lugar de un error.


Ejecutando el servidor de desarrollo a través de HTTPS


Algunos de los métodos de autenticación social que vamos a usar requieren una conexión HTTPS. El protocolo de Seguridad de la Capa de Transporte (TLS) es el estándar para servir sitios web a través de una conexión segura. El predecesor de TLS es el Protocolo de Capa de Conexiones Seguras (SSL, por sus siglas en inglés).


Aunque SSL ahora está obsoleto, en múltiples bibliotecas y documentación en línea encontrarás referencias a los términos TLS y SSL. El servidor de desarrollo de Django no puede servir tu sitio a través de HTTPS, ya que ese no es su uso previsto. Para probar la funcionalidad de autenticación social sirviendo el sitio a través de HTTPS, vamos a utilizar la extensión RunServerPlus del paquete Django Extensions.


Django Extensions es una colección de extensiones personalizadas de terceros para Django. Ten en cuenta que nunca debes usar esto para servir tu sitio en un entorno real; este es solo un servidor de desarrollo.


Utiliza el siguiente comando para instalar Django Extensions:

$ pip install django-extensions

Necesitarás instalar Werkzeug, que contiene una capa de depuración requerida por la extensión RunServerPlus de Django Extensions. Utiliza el siguiente comando para instalar Werkzeug:

pip install werkzeug


Finalmente, utiliza el siguiente comando para instalar pyOpenSSL, que es necesario para usar la funcionalidad SSL/TLS de RunServerPlus:

pip install pyOpenSSL


Edita el archivo settings.py de tu proyecto y agrega Django Extensions al ajuste INSTALLED_APPS, de la siguiente manera:

PracticaDjango/PracticaDjango/settings.py

#...
INSTALLED_APPS = [
    # Nuestras aplicaciones
    'Proyecto_web_app.apps.ProyectoWebAppConfig',
    'Servicios.apps.ServiciosConfig',
    'Blog.apps.BlogConfig',
    'Contacto.apps.ContactoConfig',
    'Tienda.apps.TiendaConfig',
    'Carro.apps.CarroConfig',
    'Autentificacion.apps.AutentificacionConfig',
    # Aplicaciones de terceros
    'django_bootstrap5',
    'social_django',
    'django_extensions',
    # Mapa del Sitio


Ahora, usa el comando de gestión runserver_plus proporcionado por Django Extensions para ejecutar el servidor de desarrollo, de la siguiente manera:

python manage.py runserver_plus --cert-file cert.crt

Hemos proporcionado un nombre de archivo al comando runserver_plus para el certificado SSL/TLS. Django Extensions generará automáticamente una clave y un certificado.

Abre https://misitio.com:8000/cuenta/login/ en tu navegador. Ahora estás accediendo a tu sitio a través de HTTPS. Ten en cuenta que ahora estamos usando https:// en lugar de http://.

Tu navegador mostrará una advertencia de seguridad porque estás usando un certificado auto generado en lugar de un certificado confiable por una Autoridad de Certificación (CA).

Si estás utilizando Google Chrome, verás la siguiente pantalla:

mensaje de advertencia del navegador


En este caso, haz clic en "Avanzado" y luego haz clic en "Acceder a 127.0.0.1 (no seguro)".

Si estás utilizando otro navegador, accede a la información avanzada mostrada por tu navegador y acepta el certificado autofirmado para que tu navegador confíe en el certificado.

Verás que la URL comienza con https:// y, en algunos casos, un icono de candado que indica que la conexión es segura. Algunos navegadores pueden mostrar un icono de candado roto porque estás utilizando un certificado autofirmado en lugar de uno confiable. Eso no será un problema para nuestras pruebas.

¡Django Extensions incluye muchas otras herramientas y características interesantes! Puedes encontrar más información sobre este paquete en https://django-extensions.readthedocs.io/en/latest/.

¡Ahora puedes servir tu sitio a través de HTTPS durante el desarrollo para probar la autenticación social con Facebook, Twitter y Google!


Autentificación usando Facebook.


Para utilizar la autenticación de Facebook para iniciar sesión en tu sitio, agrega la siguiente línea, resaltada en negrita, al ajuste AUTHENTICATION_BACKENDS en el archivo settings.py de tu proyecto:

PracticaDjango/PracticaDjango/settings.py

#...
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'Autentificacion.autentificacion.EmailAuthBackend',
'social_core.backends.facebook.FacebookOAuth2',
]

Necesitaras crearte una cuenta de desarrollador de Facebook y luego crear una nueva aplicación de Facebook.

En tu navegador abre la siguiente dirección https://developers.facebook.com/apps/. Lo primero que tienes que hacer es logearte con la cuenta de Facebook y crear una cuenta de desarrollador. Te pedirán una serie de datos para verificar que eres tu. Una vez que hayas creado la cuenta de desarrollador verás la siguiente ventana:


pantalla inicial para crear aplicación

En la parte superior derecha haz clic en Crear aplicación.

Después verás una pantalla en la que se pueden seleccionar los casos más habituales de uso entre los desarrolladores. Selecciona el que pone "Authenticate and request data from users"


Authenticate and request data from users

Luego te preguntarán si estas desarrollando un juego o no:


¿Estás creando un juego o no?

A continuación verás el siguiente formulario para crear la aplicación:


Detalles de la aplicación

Donde pone "unikgame" introduce el nombre de tu aplicación, añade un email de contacto y haz clic en crear aplicación.

Luego ve a la parte izquierda de la pantalla. Haz clic en casos de uso y a la derecha haz clic en personalizar en el apartado de Autenticación y creación de cuenta. En la siguiente pantalla verás lo siguiente:

autenticacion y creacion de cuenta - personalizar

Haz clic en Ir a guía de inicio rápido.

El sistema te pedirá que elijas la plataforma para que vas a desarrollar la aplicación tal como se muestra en la siguiente imagen:

selección de plataforma para facebook login


Selecciona la plataforma web. Verás el siguiente formulario:

configuración de la plataforma web


Aquí tienes que introducir la URL que has configurado para tu sitio web de la forma https://misitio.com:8000/. En la imagen ves como he configurado yo mi página, tu tendrás que utilizar la que hayas configurado previamente. Después haz clic en continuar. Puedes saltarte el resto de opciones de guía de inicio rápido. Haz clic en la parte superior en el botón de volver dos veces hasta que vuelvas al panel de control de la aplicación.

Ahora, en la parte izquierda de la pantalla, haz clic en configuración de la aplicación y luego en información básica.

Panel de control de facebook


Verás un formulario con unos datos similares a los siguientes:


detalles de la aplicación

Copia el identificador de la aplicación (App ID)  y la Clave secreta de la aplicación (App Secret) y añádelas al archivo settings.py del proyecto de la siguiente forma:

PracticaDjango/PracticaDjango/settings.py

SOCIAL_AUTH_FACEBOOK_KEY = 'XXX' # Facebook App ID
SOCIAL_AUTH_FACEBOOK_SECRET = 'XXX' # Facebook App Secret

Opcionalmente, puedes definir SOCIAL_AUTH_FACEBOOK_SCOPE con los permisos adicionales que quieras requerir a los usuarios de Facebook, como por ejemplo el email:

PracticaDjango/PracticaDjango/settings.py

SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']

Ahora, vuelve la panel de control de aplicaciones de Facebook y haz clic en Configuración de la aplicación y acto seguido en información básica. Añade misitio.com en el campo Dominios de la aplicación (en mi caso sera unikgame.com)

También tienes que introducir una URL pública para el campo Privacy Policy URL y otra para el campo User Data Deletion Instruction URL. El siguiente es un ejemplo que usa la página de la Wikipedia como URL Privacy Policy. Por favor, date cuenta de que deberías usar tu propia URL válida:


Política de privacidad y condiciones de uso


Haz clic en guardar cambios. Luego, en la parte izquierda del menú hay que entrar en Casos de uso, luego a la derecha hacer clic en Personalizar y en la siguiente pantalla hacer clic en Ir a Configuración.

Comprueba que solo los siguientes ajustes estén activos:

• Client OAuth Login

• Web OAuth Login

• Enforce HTTPS

• Embedded Browser OAuth Login

• Used Strict Mode for Redirect URIs

y en el campo URI de redireccionamiento de OAuth válidos hay que introducir https://misitio.com:8000/social-auth/complete/facebook/ en donde misitio es el nombre de tu aplicación, en mi caso unikgame.com. Será algo como esto:

Cliente Oauth settings


Abre la plantilla registration/login.html de la aplicación Autentificacion y añade el siguiente código resaltado que añadirá el botón para registrarnos con la cuenta de Facebook en la parte inferior derecha de la plantilla:

PracticaDjango/Autentificacion/templates/registration/login.html

#...
<div class="login-form">
    <form action="{% url 'login' %}" method="post">
        {% csrf_token %}
        <div class="container w-25 bg-primary rounded-1">
            {% bootstrap_form form %}
            <input type="hidden" name="next" value="{{ next }}" />
            <p><input type="submit" value="Log-in"></p>
            <!-- {{ form.as_p }} -->
    </form>
    <p>
        <a href="{% url 'password_reset' %}" style="color:white">
            ¿Olvidaste tu contraseña?
        </a>
    </p>
</div>
<div class="social">
    <ul>
        <li class="facebook">
            <a href="{% url 'social:begin' 'facebook' %}">
                Haz Login con Facebook
            </a>
        </li>
    </ul>
</div>
{% endblock %}

Utiliza el comando de administración runserver_plus que nos proporciona Django Extensions para ejecutar el servidor de desarrollo de la siguiente manera:

python manage.py runserver_plus --cert-file cert.crt

Abre la siguiente dirección en tu navegador https://misitio.com:8000/cuenta/login/. Verás algo parecido a lo siguiente:


pagina para loguearse con Facebook

Haz clic en el botón Haz Login con Facebook. Serás redirigido a Facebook y verás un cuadro de dialogo pidiendo tu permiso para que tu aplicación acceda a tu perfil público de Facebook.

Permisos de la aplicación

Verás una advertencia que indica que necesitas enviar la aplicación para revisión de inicio de sesión. Haz clic en el botón Continuar como...

Serás conectado y redirigido a la página de inicio de tu sitio. Recuerda que has establecido esta URL en la configuración LOGIN_REDIRECT_URL. Como puedes ver, agregar autenticación social a tu sitio es bastante sencillo.


Autentificándose usando Twitter (ahora X)


Para loguearte usando twitter, añade la siguiente línea resaltada a los ajustes de autentificación del archivo settings.py de la aplicación.

PracticaDjango/PracticaDjango/settings.py

#...
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'Autentificacion.autentificacion.EmailAuthBackend',
'social_core.backends.facebook.FacebookOAuth2',
'social_core.backends.twitter.TwitterOAuth',
]

Necesitarás una cuenta de desarrollador de Twitter. Abre la dirección https://developer.twitter.com/ en tu navegador y haz clic en Sign Up. 

Después de crear una cuenta de desarrollador de Twitter, accede al panel de administración en la siguiente dirección https://developer.twitter.com/en/portal/dashboard. El panel de control debería tener un aspecto similar a este:

twitter developer poertal dashboard


Haz clic el botón "Create Project". Verás la siguiente pantalla:

Twitter create project screen – Use case

Introduce el nombre de tu proyecto y haz clic en Next.

En "Use Case" selecciona la opción que mejor se ajuste a porqué quieres usar el Api Twitter.  Esto no afectará a la configuración. 

descripción del uso del api de twitter


Después verás la siguiente pantalla:

Twitter create project screen – Project description

Introduce una breve descripción para tu proyecto y haz clic en Next. El proyecto ya está creado y verás la siguiente pantalla.

Twitter application configuration


Crearemos una nueva aplicación. Haz clic en Create New. Verás la siguiente pantalla para configurar la aplicación. 


En App name introduce el nombre de tu aplicación. Twitter no te permitirá introducir el nombre de un proyecto que ya exista por lo que debes ingresar un nombre que esté disponible. Haz clic en Next. Twitter te mostrará un error si el nombre que has introducido ya existe.

Después de escoger un nombre que este disponible, verás la siguiente pantalla.

Twitter application configuration – generated API keys

Copia de App Key y de Api Key Secret y pégalo en el archivo settings.py de tu proyecto.

PracticaDjango/PracticaDjango/settings.py

SOCIAL_AUTH_TWITTER_KEY = 'XXX' # Twitter API Key
SOCIAL_AUTH_TWITTER_SECRET = 'XXX' # Twitter API Secret

Después haz clic en App Settings. Después verás la siguiente pantalla en la que tendrás que volver a hacer clic en Set up.

configuración final de la aplicación

Al hacerlo tendrás que rellenar una serie de datos que están todos en la misma página. Son los siguientes:

conceder permisos a la aplicación

tipo de aplicación - web

En tipo de aplicación selecciona Web App.


En la pantalla de App Info introduce los siguientes detalles sobre tu aplicación:

Under General Authentication Settings, enter the following details of your application:

• Callback URI / Redirect URL: https://misitio.com:8000/social-auth/complete/twitter/

• Website URL: https://misitio.com:8000/

Los ajustes deberían parecerse a esto:


Twitter authentication URL configuration


Finalmente haz clic en Save. Ahora verás la siguiente pantalla que incluye el Client Id y el Client Secret.

twitter client id y client secret

No los necesitarás para la autentificación como cliente porque utilizaremos la clave Api Key y la clave Api Key Secret en su lugar. Sin embargo si te interesa puedes copiarlos y guardarlos en un lugar seguro. Haz clic en Done.

Verás otra pantalla que te recuerda que guardes tu Client Secret. 

Twitter Client Secret reminder

Haz clic en "Yes, I saved it".  

Abre la plantilla registration/login.html de la aplicación Autentificacion y añade el siguiente código resaltado que añadirá el botón para registrarnos con la cuenta de Twitter en la parte inferior derecha de la plantilla:


PracticaDjango/Autentificacion/templates/registration/login.html

#...

  <div class="social">
    <ul>
        <li class="facebook">
            <a href="{% url 'social:begin' 'facebook' %}">
                Login con Facebook
            </a>
        </li>
        <li class="twitter">
            <a href="{% url 'social:begin' 'twitter' %}">
                Login con Twitter
            </a>
        </li>
    </ul>
</div>

Utiliza el comando de administración runserver_plus que nos proporciona Django Extensions para ejecutar el servidor de desarrollo de la siguiente manera:

python manage.py runserver_plus --cert-file cert.crt

Abre la siguiente dirección en tu navegador https://misitio.com:8000/cuenta/login/. Busca en la parte inferior derecha y haz clic en "Login con Twitter". La aplicación te redireccionará a Twitter, donde te preguntarán si autorizas a tu aplicación, tal como se muestra en la siguiente imagen:

Twitter user authorization screen

Introduce tus datos e inicia sesión. Verás brevemente la siguiente página mientras eres redirigido a la página principal de la aplicación.

Twitter user authentication redirect page



Autentificación usando Google.


Google ofrece autenticación social utilizando OAuth2. Puedes leer sobre la implementación de OAuth2 de Google en https://developers.google.com/identity/protocols/OAuth2.

Para implementar la autenticación utilizando Google, agrega la siguiente línea resaltada en azul en la configuración AUTHENTICATION_BACKENDS en el archivo settings.py de tu proyecto:

PracticaDjango/Autentificacion/templates/registration/login.html

AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'Autentificacion.autentificacion.EmailAuthBackend',
'social_core.backends.facebook.FacebookOAuth2',
'social_core.backends.twitter.TwitterOAuth',
'social_core.backends.google.GoogleOAuth2',
]
Primero, necesitarás crear una clave API en tu Consola de Desarrollador de Google. Abre https://console.cloud.google.com/projectcreate en tu navegador. Verás la siguiente pantalla:

The Google project creation form

En Project name introduce el nombre de tu proyecto (En mi caso unikgame) y haz clic en el boton Create.

Cuando el nuevo proyecto esté listo, asegúrate de que el proyecto esté seleccionado en la barra de navegación superior de la siguiente manera:

The Google Developer Console top navigation bar


Después de que se cree el proyecto, a la izquierda en el panel que pone "Apis y Servicios" haz clic en credenciales.

Google APIs and services menu


Verás la siguiente pantalla:

Google API creation of API credentials

Haz clic en crear credenciales y luego en ID de cliente de OAuth.

Google te pedirá primero que aceptes la pantalla de consentimiento:

The alert to configure the OAuth consent screen

Configuraremos la página que se mostrará a los usuarios para que otorguen su consentimiento para acceder a tu sitio con su cuenta de Google. Haz clic en el botón CONFIGURAR PANTALLA DE CONSENTIMIENTO. Serás redirigido a la siguiente pantalla:

User type selection in the Google OAuth consent screen setup


Escoge "External" para el tipo de uso y haz clic en el botón "Create". Verás la siguiente pantalla:

Google OAuth consent screen setup


En App name introduce el nombre de tu aplicación (Unikgame en mi caso) y tu correo electrónico como correo de soporte. 

En "Authorised Domains" introduce misitio.com (en mi caso unikgame.com) de la siguiente forma:



Google OAuth authorized domains


Ingresa tu correo electrónico en la sección 'Información de contacto del desarrollador' y haz clic en GUARDAR Y CONTINUAR. En el paso 2, 'Ámbitos', no cambies nada y haz clic en GUARDAR Y CONTINUAR.

En el paso 3, 'Usuarios de prueba', añade tu usuario de Google a 'Usuarios de prueba' y haz clic en GUARDAR Y CONTINUAR de la siguiente manera:

Google OAuth test users


Verás un resumen de la configuración de tu pantalla de consentimiento. Haz clic en 'Volver al panel'.

En el menú de la barra lateral izquierda, haz clic en 'Credenciales' y luego en 'Crear credenciales' y después en 'ID de cliente de OAuth'.

Como siguiente paso, introduce la siguiente información:
Tipo de aplicación: Selecciona Aplicación web
Nombre: Ingresa el nombre de tu aplicación, en mi caso unikgame
Orígenes autorizados de JavaScript: Agrega https://misitio.com:8000
URIs de redireccionamiento autorizados: Agrega https://misitio.com:8000/social-auth/complete/googleoauth2/


The Google OAuth client ID creation form



The Google OAuth client ID creation form


Pulsa el botón CREAR. Obtendrás tus claves de 'ID de cliente' y 'Secreto de cliente':

Google OAuth Client ID and Client Secret


Añade ambas claves a tu archivo settings.py, de esta manera:

PracticaDjango/PracticaDjango/settings.py

#...
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = "XXX" # Google API Key
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = "XXX" # Google Client Secret
Edita la plantilla de registro/login.html y agrega el siguiente código resaltado en azul al
elemento <ul>:

PracticaDjango/Autentificacion/templates/registration/login.html

#...
<div class="social">
    <ul>
        <li class="facebook">
            <a href="{% url 'social:begin' 'facebook' %}">
                Login con Facebook
            </a>
        </li>
        <li class="twitter">
            <a href="{% url 'social:begin' 'twitter' %}">
                Login con Twitter
            </a>
        </li>
        <li class="google">
            <a href="{% url 'social:begin' 'google-oauth2' %}">
                Login con Google
            </a>
        </li>
    </ul>
</div>
Utiliza el comando de gestión runserver_plus proporcionado por Django Extensions para ejecutar el servidor de desarrollo de la siguiente manera:

python manage.py runserver_plus --cert-file cert.crt

Abre https://misitio.com:8000/account/login/ en tu navegador. En la parte inferior derecha haz clic en "Login con Google". Deberías poder loguearte y ser redireccionado a la página de inicio de la aplicación.



Creación de un perfil para usuarios que se registran con autenticación social. 



Cuando un usuario se autentica utilizando la autenticación social, se crea un nuevo objeto de Usuario si no existe un usuario asociado a ese perfil social. Python Social Auth utiliza un conjunto de funciones que se ejecutan en un orden específico durante el flujo de autenticación. Estas funciones se encargan de obtener los detalles del usuario, crear un perfil social en la base de datos y asociarlo a un usuario existente o crear uno nuevo.

Actualmente, no se crea un objeto de Perfil (Profile)  cuando se crean nuevos usuarios a través de la autenticación social. Aunque esto lo tenemos solventado en cierta forma ya que cuando editamos el usuario en esa vista introdujimos lo siguiente:


PracticaDjango/Autentificacion/views.py

#...
@login_required
def edit(request):
    try:
        profile = request.user.profile
    except Profile.DoesNotExist:
        profile = None
        
    if request.method == "POST":
        user_form = UserEditForm(instance=request.user, data=request.POST)
        if profile:
            profile_form = ProfileEditForm(
                instance=profile, data=request.POST, files=request.FILES
            )
        else:
Si el perfil existe se asigna a la variable "profile" y si no se crea una con el valor de None lo que evita que nos de un error al usar la vista.

Sin embargo para que esto todo mejor, vamos a agregar un nuevo paso al pipeline para crear automáticamente un objeto de Perfil en la base de datos cuando se crea un nuevo usuario.

Agrega la siguiente configuración SOCIAL_AUTH_PIPELINE al archivo settings.py de tu proyecto:

PracticaDjango/PracticaDjango/settings.py

#...
SOCIAL_AUTH_PIPELINE = [
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
]
Este es el flujo de autenticación predeterminado utilizado por Python Social Auth. Consiste en varias funciones que realizan diferentes tareas al autenticar a un usuario. Puedes encontrar más detalles sobre el flujo de autenticación predeterminado en https://python-social-auth.readthedocs.io/en/latest/pipeline.html.

Construyamos una función que cree un objeto de Perfil en la base de datos cada vez que se crea un usuario nuevo. Luego agregaremos esta función al flujo de autenticación social.

Edita el archivo Autentificacion/autentificacion.py y agrega el siguiente código:

PracticaDjango/Autentificacion/autentificacion.py

#...
def create_profile(backend, user, *args, **kwargs):
    """
    Create user profile for social authentication
    """
    Profile.objects.get_or_create(user=user)
La función create_profile toma dos argumentos requeridos:

backend: El backend de autenticación social utilizado para la autenticación del usuario. Recuerda que has agregado los backends de autenticación social al ajuste AUTHENTICATION_BACKENDS en tu proyecto.

user: La instancia de Usuario del usuario nuevo o existente autenticado.
Puedes revisar los diferentes argumentos que se pasan a las funciones del flujo en https://pythonsocial-
auth.readthedocs.io/en/latest/pipeline.html#extending-the-pipeline.

En la función create_profile, verificamos que haya un objeto de usuario presente y utilizamos el método get_or_create() para buscar un objeto de Perfil para el usuario dado, creándolo si es necesario.

Ahora, necesitamos agregar la nueva función al flujo de autenticación. Agrega la siguiente línea resaltada en negrita al ajuste SOCIAL_AUTH_PIPELINE en tu archivo settings.py:

PracticaDjango/PracticaDjango/settings.py

#...
SOCIAL_AUTH_PIPELINE = [
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'social_core.pipeline.user.create_user',
'Autentificacion.autentificacion.create_profile',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
]
Hemos añadido la función create_profile después de social_core.pipeline.create_user. En este punto, una instancia de Usuario está disponible. El usuario puede ser un usuario existente o uno nuevo creado en este paso del flujo. La función create_profile utiliza la instancia de Usuario para buscar el objeto de Perfil relacionado y crear uno nuevo si es necesario.

Accede a la lista de usuarios en el sitio de administración en https://misitio.com:8000/admin/auth/user/. Elimina cualquier usuario creado mediante autenticación social.

Luego, abre https://misitio.com:8000/account/login/ e inicia sesión mediante autenticación social para el usuario que eliminaste. Se creará un nuevo usuario y ahora también se creará un objeto de Perfil. Accede a https://mysite.com:8000/admin/account/profile/ para verificar que se haya creado un perfil para el nuevo usuario.

Puedes encontrar el código de es Post en el siguiente enlace de GITHUB.