DEV Community

Maximiliano Burgos
Maximiliano Burgos

Posted on

Diario de Python | #12. Color Choice: Autenticación por Token

El módulo de autenticación de Django ya viene incorcopado con el framework en si, y cuando lanzamos:

python manage.py migrate

Se migran las tablas que permiten el manejo de usuarios. Esto me resuelve gran parte del trabajo de sesiones, lo cual se agradece bastante.

Manos a la obra

Existe una clase AbstractUser, la cual podríamos heredar para generar nuestro propio usuario personalizado y agregar los campos que necesitemos. La voy a armar sin atributos, de momento, para que si en el futuro necesitamos agregar información especial al usuario, ya tengamos nuestra clase generada.

En models.py declaro el nuevo modelo User:

from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    pass
Enter fullscreen mode Exit fullscreen mode

Luego en settings.py le digo a Django que reconozca este modelo como su entidad User de su módulo de auth de la app api:

AUTH_USER_MODEL = 'api.User'
Enter fullscreen mode Exit fullscreen mode

Armo la migración y al ejecutarla me dice:

ValueError: The field admin.LogEntry.user was declared with a lazy reference to 'api.user', but app 'api' doesn't provide model 'user'.
The field api.Vote.user was declared with a lazy reference to 'api.user', but app 'api' doesn't provide model 'user'.
Enter fullscreen mode Exit fullscreen mode

Necesito declarar a Vote, el cual tiene una clave foranea de User, que se trata de mi usuario y no el del módulo de Django. El problema es que las migraciones ya corrieron anteriormente con la relación anterior, por lo cual no me las va a tomar.

Borro mi archivo de SQLite3.db y lo recreo con las migraciones, para que Django entienda las nuevas relaciones con mi usuario personalizado.

Auth Token y Auth User

Llegados a este punto, ya tengo un usuario personalizado, unido al módulo de autenticación de Django. Ahora voy a armar un endpoint de login en views.py, y lo voy a combinar con un componente de Auth Token que viene con DRF:

@api_view(['POST'])
def user_auth(request):
    username = request.data.get('username')
    password = request.data.get('password')

    if not username or not password:
        return Response({'error': 'Se debe indicar usuario y contraseña'}, status=status.HTTP_204_NO_CONTENT)

    user = authenticate(request, username=username, password=password)
    if user is None:
        return Response({'error': 'El usuario o la contraseña son incorrectos'}, status=status.HTTP_400_BAD_REQUEST)

    token, created = Token.objects.get_or_create(user=user)
    return Response({'token': token.key}, status=status.HTTP_200_OK)
Enter fullscreen mode Exit fullscreen mode

Luego defino la ruta en urls.py:

urlpatterns += [
    path('auth', user_auth, name='api-auth')
]
Enter fullscreen mode Exit fullscreen mode

A este método accedo mediante "POST /api/auth" con un JSON que contenga mi usuario y contraseña.

Pero, ¿qué hace mi vista user_auth?. Básicamente hace lo siguiente:

  • Toma del request el user y pass.
  • Si alguno de estos valores no existe, devuelve un error.
  • Luego, con la función authenticate corre el proceso de login.
  • Si el login es correcto, llama al método get_or_create del modelo Token, previamente migrado por haber importado el módulo authtoken.
  • Finalmente devuelve dicho token, que nos servirá para mantener una sesión y decirle a la API quiénes somos.

Vamos a probarlo en Postman haciendo un POST a la ruta anteriormente indicada, con un JSON Body como este:

{
 "username": "admin",
 "password": "123"
}
Enter fullscreen mode Exit fullscreen mode

Y nos devolverá lo siguiente:

Postman POST

Conclusiones

Quizá ahora la autenticación por Token parezca innecesaria, dado que no lo aplicamos a ningún endpoint, pero en el próximo capítulo van a ver la potencia de este simple string, y como impacta en nuestro objeto request.

¡Nos vemos en el próximo!

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay