jueves, 14 de marzo de 2019

Json Web Token en Django Rest FrameWork - La forma fácil

#jwt  #drf  #auth #django #rest #framework #JsonWebToken #Token #python #Udemy #course #free #class

JWT, el acrónimo (en inglés) de Json Web Token, es una estrategia de autenticacón usada para aplicaciones CLIENTE/SERVIDOR donde el cliente es una aplicación web que usa Django, JavaScript o algún otro framework para front end como React, Angular, VueJS, etc.

En este tutorial voy a tratar de explicar la forma más fácil de implementar la autenticación JWT en un RestFul Api hecho con Django Rest FrameWork (DRF).  Menciono la manera fácil, porque hay otra forma (lo hablaré en una clase extra del curso) un poco más compleja.  Con lo que veremos en este tutorial, bien podrás implementar JWT en tu proyecto DRF.

Aclaraciones


  • Para las consultas o peticiones al ENDPOINT del API, estaré usando CURL
  • El proyecto a trabajar forma parte de lo que se ha hecho en el curso RestFul API con Python usando Django Rest FrameWork.  Este tutorial cubre la implementación de JWT para dicho proyecto.
  • Se asume que estás trabajando con un entorno virtual activado, así la instalación se realizará únicamente en dicho entorno virtual.
  • Será la forma fácil, porque usaremos la librería djangorestframework_simplejwt.

¿Cómo funciona JWT?

JWT es sólo un token de autorización que debe agregarse en el encabezado de todas las peticiones, para las cuales se requiere mostrar el recurso para usuarios autorizados.

El encabezado para enviar el token, debería verse algo así:

 curl http://127.0.0.1:8000/api/v1/productos/ -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTUyNTkyMzc3LCJqdGkiOiJiNTM0NWYzNTU5Yjc0ZDlmODM3YjBhMWIyN2NiYjk3NSIsInVzZXJfaWQiOjJ9.s3w6Li6usWzY7XM5W80jG2zwbVHsf73fgYM9kt8Fz10"  

Como vemos en el encabezado se envía Autorization y el tipo de token a enviar es Bearer.

El JWT se adquiere luego de autenticarse en el api al cual se le envío el usuario y la contraseña, esto regresará el access token y el refresh token.

El access token por lo general tiene una vida corta (expira por lo general en 5 minutos, podría ser configurable).

El refresh token, vive un poco más (24 horas, igual se podría configurar).  Se puede comparar con la autenticación por sesión.  Luego que éste expiere, el usuario deberá realizar un full login nuevamente.

Instalación y Configuración

Para instalar, debemo ejecutar desde la consola


 pip install djangorestframework_simplejwt  

Luego debemos de realizar la siguiente configuración

settings.py

 REST_FRAMEWORK = {  
   'DEFAULT_AUTHENTICATION_CLASSES': [  
     'rest_framework_simplejwt.authentication.JWTAuthentication',  
   ],  
 } 

urls.py 

La librería seleccionada, tiene la ventaja que ya trae vistas para autenticarse y para refrescar el token, a como podemos ver en el contenido de las rutas.


 from rest_framework_simplejwt import views as jwt_views  
 .  
 .  
 .  
 path('v5/token',jwt_views.TokenObtainPairView.as_view(), name='token_obtain_pair'),  
 path('v5/token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh'), 

Probando aplicación

Para probar, vamos a usar la vista de listar productos del curso.

 class ProductoList(generics.ListCreateAPIView):  
   queryset = Producto.objects.all()  
   serializer_class = ProductoSerializer  


que tiene la ruta


 path('v1/productos/',ProductoList.as_view(), name='producto_list'),  

Primero que todo debemos autenticarnos, con la librería seleccionada tiene la particularidad que sólo invoquemos la vista TokenObtainPairView establecidad en el archivo de rutas bajo la url /api/v5/token y sólo le pasaremos como cabecera el username y el password, por eso es la forma fácil.

le pasaré el usuario daniel.bojorge y la clave 1234567.



 curl -X POST http://127.0.0.1:8000/api/v5/token -d "username=daniel.bojorge&password=1234567."  

Lo que devuelve algo así:


 {  
  "refresh":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTU1MjY4MjkyNywianRpIjoiMTA0ODlkNjdmZWQ5NDFkYzlhNWRlMmY4ZTg2OTFiNmUiLCJ1c2VyX2lkIjoyfQ.kDSm6ULrW5c5BCb1TisVVH440FnDwfbT3MiANlCMM0Y",  
  "access":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTUyNTk2ODI3LCJqdGkiOiI4N2U3NTMxMGUyMzY0ZDc5OTliYjU2NWNmNjRlZjcwOSIsInVzZXJfaWQiOjJ9._rRyKZhwmIuQIz9ks_STq8Z7t5cqz8VpPfAMjvaOm7Q"  
 }  

Ya la librería trae la opción de autenticarse, por tanto sólo requiere que se tenga creado el usuario.

Para poder hacer alguna consulta, se debe agregar en la cabecera el access token


 curl http://127.0.0.1:8000/api/v1/productos/ -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTUyNTk2ODI3LCJqdGkiOiI4N2U3NTMxMGUyMzY0ZDc5OTliYjU2NWNmNjRlZjcwOSIsInVzZXJfaWQiOjJ9._rRyKZhwmIuQIz9ks_STq8Z7t5cqz8VpPfAMjvaOm7Q"  



Lo que eventualmente devolverá la respuesta solicitada.


 [{"id":7,"descripcion":"Desarrollo Web con Python usando Django","fecha_creado":"2018-10-01T12:11:37.090335Z","vendido":false,"subcategoria":1},{"id":8,"descripcion":"Replicacion de Base de Datos con SymmetricDS","fecha_creado":"2018-11-01T12:11:37.090335Z","vendido":false,"subcategoria":2},{"id":9,"descripcion":"Desarrollo de Aplicaciones en Capas","fecha_creado":"2017-08-01T12:11:37.090335Z","vendido":false,"subcategoria":3},{"id":10,"descripcion":"Domina ORM de Django","fecha_creado":"2019-01-04T12:11:37.090335Z","vendido":false,"subcategoria":4},{"id":11,"descripcion":"Introducción a Entity FrameWork","fecha_creado":"2017-08-05T12:11:37.090335Z","vendido":false,"subcategoria":4},{"id":12,"descripcion":"Álgebra Baldor","fecha_creado":"2015-05-05T12:11:37.090335Z","vendido":false,"subcategoria":5},{"id":14,"descripcion":"Poemas","fecha_creado":"1988-01-01T16:00:00Z","vendido":true,"subcategoria":5},{"id":15,"descripcion":"Nuevo de Azul","fecha_creado":"1988-01-01T16:00:00Z","vendido":true,"subcategoria":5},{"id":13,"descripcion":"Nuevo de Azul nuevo","fecha_creado":"1988-01-01T16:00:00Z","vendido":true,"subcategoria":5}]  

Si pasan 5 minutos, la respuesta será de token inválido


 {"detail":"Given token not valid for any token type","code":"token_not_valid","messages":[{"token_class":"AccessToken","token_type":"access","message":"Token is invalid or expired"}]}  


Si tratan de invocar el api con un token incorrecto, tendrán la respuesta con algo así:


 {"detail":"Given token not valid for any token type","code":"token_not_valid","messages":[{"token_class":"AccessToken","token_type":"access","message":"Token has wrong type"}]}  



Y si tratan de invocar sin ningún token.



Bueno y así rápidamente vimos cómo es fácil implementar JWT con Django Rest FrameWork.    Espero que este artículo te sea de utilidad

Si tienes interés en el curso, te dejo este enlace para que lo examines y si te inscribes con este enlace, obtendrás un cupón del 90%



0 comentarios:

Publicar un comentario

¿Tienes algún comentario? ¿Qué te ha parecido este artículo? Cuéntalo.

 
>