Taller de Sistemas de Computación 2016

De Departamento de Informatica
Revisión a fecha de 23:59 3 dic 2016; Evera (Discusión | contribuciones)
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Saltar a: navegación, buscar

Contenido

Temas de Investigación

Configuración de SELinux para servicios HTTP

La configuración de SElinux para APACHE y NGINX se encuentra directamente en el tema 6.1. Además, en el tema 6.2 se encuentra la respectiva configuración para algunas bases de datos que se encuentren en un sistema con SElinux activado.

Patrón MVC en Ruby on Rails

Grupo 14
  • Carlos Bugueño
  • Eduardo Ramírez
  • Oscar Duarte

Arquitectura MVC

MVC es un patrón de arquitectura de software que se centra principalmente en la separación del código en 3 areas: Modelo, Vista y Controlador. El Modelo se encarga de representar y manipular los datos de la aplicación, es decir, tiene directa relación con la base de datos. La vista se encarga de mostrar los datos al usuario de una forma adecuada y recibir también el input. El controlador actúa como intermediario entre ambas entidades. Una consulta de un usuario a un sistema Rails, que sigue el patrón MVC, tiene el siguiente flujo [1]:

Flujo de consulta en Arquitectura MVC
  1. Un usuario, a traves de un navegador, hace la consulta al servidor, como por ejemplo http://sitio.com/usuario/mostrar/2
  2. El servidor usa el archivo de rutas de Rails para saber que Controlador usar y le envía los parámetros y datos en la consulta
  3. El Controlador recibe los datos y ejecuta el método correspondiente, haciendo llamada a algún Modelo
  4. El Modelo ejecuta la lógica necesaria para completar la consulta y se conecta con la base de datos (DBMS)
  5. El Controlador recibe el output del modelo y envía lo correspondiente a la Vista
  6. La Vista lo ordena en HTML y finalmente el controlador le envía al servidor la página con el output formateado
  7. El servidor envía la respuesta al navegador quien la parsea y muestra al usuario

Modelos

Los Modelos representan en Rails la capa de abstracción y acceso de datos [2]. Se representan en Rails con clases que heredan de ActiveRecord::Base. Eso faculta a la clase para comunicarse directamente con los datos. Cada método debe relacionarse con algún tipo de consulta a la BD. Por ejemplo el método User.getAllWithJob debe realizar todo el proceso para obtener todos los usuarios que tengan trabajo. Cada clase mapea una entidad de la base de datos, es decir, una tabla. Por ejemplo la tabla users será mapeada a la clase User. Por convención de Rails las tablas son con plural y minúscula, mientras que las clases en singular y mayúscula. Cabe mencionar que el framework tiene como parte de la filosofía la "Convención por sobre la Configuración" [3].

Ejemplo de definición de Modelo simple

Uso de Modelos

Rails genera métodos CRUD (Create, Read, Update and Delete) automáticamente en base a los atributos de las entidades [4], por ejemplo si la entidad tiene un atributo name existirá el método find_by_name, con el que se podrá filtrar según nombre en la tabla. Las clases de modelos ya tienen varios métodos que facilitan mucho las tareas esenciales con datos de BDs. Estos métodos son los que vienen definidos en los ActiveRecord. Como se ve en el ejemplo la nueva instancia de User esta mapeado a un nuevo registro de la base de datos pero que aún no se guarda. Se le pueden hacer todo tipo de modificaciones para luego guardarse con save. También se puede manipular el registro directamente modificando el o los objetos obtenidos como resultado de una consulta.

Ejemplo de uso de un Modelo

Asociaciones

En Rails, las relaciones entre entidades del modelo de datos son expresadas a través de Asociaciones. La existencia de relaciones bien definidas dentro de los modelos es esencial para facilitar las consultas que requieran más de una entidad, por ejemplo, obtener todos los cursos que dicta un profesor. Esto se lograría fácilmente con profesor.cursos . Las asociaciones más comunes son

  • belongs_to: cada instancia del modelo "pertenece" a una instancia del otro modelo
  • has_one: cada instancia de un modelo contiene o posee una instancia de otro modelo
  • has_many: Asociación del tipo uno es a muchos
  • has_and_belongs_to_many: Asociación del tipo muchos a muchos
Asociaciones (y otros métodos) dentro de un Modelo

Controladores

Los controles hacen de interfaz entre el Modelo y las Vistas [5]. Se encargan de tomar y filtrar parámetros pasados por GET y POST. También maneja las cookies y todo lo relacionado con la autenticación y seguridad de las sesiones. Se encarga de empaquetar datos para enviar a la vista y redirigir a las vistas correspondientes.

El Router de Rails se encarga de redireccionar una consulta de un servidor al Controlador y método correspondiente en base al archivo de rutas del sistema. Por ejemplo la linea GET '/notes/:id' => 'notes#show' indica que una consulta del GET a la URL sistema.cl/notes/2 debe ser manejada por el controlador de las notas, es decir, NotesController (por convención) y a su vez por el método show definido en este. Además se le entregará al controlador el id en cuestión por parámetro.

Ejemplo de Controlador en Rails

Vistas

Las Vistas muestran el resultado de todo el procesamiento de una consulta [6]. Rails usa archivos .html.erb para permitir código Ruby mezclado con HTML. Es altamente no recomendado realizar cualquier tipo de procesamiento de datos en las Vistas, para mantener el patrón MVC intacto. Solo se recomienda usar lo necesario para iterar sobre estructuras con los datos a mostrar. Todo el código pesado debe en los Controladores y Modelos. Los datos a mostrar deben ser enviados a la vista especificando los nombres de las variables con un "@", por ejemplo "@usuarios". Luego en la Vista se puede escribir código Ruby dentro de <%  %> o en caso de ser necesario escribir el output del código en la pagina web se usa <%=  %>

Muchas vistas son creadas automáticamente por el framework producto de la generación de Controladores con los comandos por consola, lo que facilita mucho el desarrollo. Así, al especificar que un Controlador tiene el método show, se crea la ruta y la vista para show.

Ejemplo de Vista en Rails

Bibliografía

1. Flujo general dentro de un sistema Ruby on Rails, http://ruby.about.com/od/rubyonrails/ss/Rails-Application-Flow.htm

2. AciveRecord, capa de datos en Rails, http://guides.rubyonrails.org/active_record_basics.html

3. Convención sobre Configuración en Rails, http://guides.rubyonrails.org/active_record_basics.html#convention-over-configuration-in-active-record

4. CRUD en Rails, http://guides.rubyonrails.org/active_record_basics.html#crud-reading-and-writing-data

5. Controladores en Rails, http://guides.rubyonrails.org/action_controller_overview.html

6. Vistas en Rails, http://guides.rubyonrails.org/layouts_and_rendering.html

Patrón MVC en Django

Grupo 5
  • Daniel Quinteros
  • Fernando Iturbe
  • Iván Lazo

¿Qué es MVC?

El modelo–vista–controlador (MVC) es un patrón de arquitectura de software, que separa los datos y la lógica de negocio de una aplicación de la interfaz de usuario y el módulo encargado de gestionar los eventos y las comunicaciones. Para ello MVC propone la construcción de tres componentes distintos que son el modelo, la vista y el controlador, es decir, por un lado define componentes para la representación de la información (modelo), y por otro lado para la interacción (controlador) del usuario (vista).

Este patrón de arquitectura de software se basa en las ideas de reutilización de código y la separación de conceptos, características que buscan facilitar la tarea de desarrollo de aplicaciones y su posterior mantenimiento [7]

  • Modelo se refiere a la capa de acceso de datos
  • Vista se refiere a la parte del sistema que selecciona qué mostrar y cómo mostrar
  • Controlador se refiere a la parte del sistema que decide qué mostrar al usuario, dependiendo de la entrada, y se encarga del acceso al modelo según sea necesario.

En Django

Un proyecto es una instancia de un cierto conjunto de aplicaciones de Django, más las configuraciones de esas aplicaciones. Una aplicación es un conjunto portable de una funcionalidad de Django, típicamente incluye modelos y vistas, que conviven en un solo paquete de Python. La “vista” describe el dato que es presentado al usuario. No es necesariamente cómo se ve el dato, sino qué dato se muestra. La vista describe cuál dato ve, no cómo lo ve. Es una distinción sutil. Así pues, una “vista” es la función de callback en Python para una URL en particular, porque esta función describe cuál dato es presentado. Además, es sensato separar el contenido de la presentación que es donde entran las plantillas. En Django, una “vista” describe cual dato es presentado, pero una vista normalmente lo delega a una plantilla, la cual describe cómo se presenta el dato. [8]


Funcionamiento del MTV de Django


Modelo

Modelo en Django

Es la representación de la información (una interfaz de la data) Esto abarca la base de datos en conjunto con el código en Python para el manejo de clases, que encaja completamente con la estructura de las bases de datos. El modelo define los datos almacenados, se encuentra en forma de clases de Python.

Una clase que hereda de object y que al crearse una instancia se inicia en 0,0. Todos los métodos de clase reciben como primer parámetro “self” [9]. Además, como se puede ver antes, las clases se pueden heredar, etc.

Una vez definidos nuestro modelos (ORM, mapeo objeto-relacional) hacemos una migración, básicamente es decirle a django que hay cambios y que los ejecute (makemigrations identifica cambios, los informa y crea la migración, por decirlo de alguna forma “escribe el sql a ejecutar”, luego migrate realiza los cambios - migraciones - preparados).

Una vez creados los modelos Django provee una API para manejarlos (crear, recuperar, actualizar y eliminar - CRUD: create, retrieve, update and delete usando Manager - interface que provee operaciones de consulta a la BD) [14]

Controlador

Controlador en Django

El controlador es el corazón del sistema, maneja pedidos y respuestas, Controla el flujo de la información entre el modelo y la vista, es decir, maneja la información que es pasada hacia la base de datos y la cual es pasada a la vista.

Una “view” es donde está la lógica de la aplicación, la cual requiere información desde el modelo, el cual da una respuesta que puede ser un HTML, un error o un documento XML. El archivo a que se utiliza es views.py.

Para determinar qué view utilizar se hace uso del urlresolver, basado en las expresiones regulares URLS en python.

  • ^ denota el principio del texto
  • $ denota el final del texto
  • \d representa un dígito
  • + indica que el ítem anterior debería ser repetido por lo menos una vez
  • * indica que el ítem anterior debería ser repetido 0 o más veces
  • ( ) para encerrar una parte del patrón
QuerySet

Un QuerySet es una lista de objetos de un modelo determinado, que permite leer, filtrar y ordenar datos de una base de datos. [15]

QuerySet API reference [16]
  • Métodos que retornan nuevas QuerySets
  • Métodos que no retornan QuerySets
  • Búsqueda de campos (WHERE clause)


Vista (Template)

TemplateTags en Django

Es la interfaz de usuario, Django separa la vista en dos, la parte HTML y el código python (llamadas views) que lo renderiza. Por defecto trae una interfaz de administrador con la capacidad de editar (CRUD) los modelos generados. Se le llama Plantilla o Template. Es un puente entre controlador y el navegador (por eso se le suele llamar MTV) por lo que el controlador sería View.

Una plantilla es un archivo que podemos reutilizar para presentar una gran cantidad de información de una forma consistente. Esto es exactamente lo que las views se supone que hacen: conectar modelos con plantillas. Importamos los modelos a las vistas, mediante los queryset (conjunto de consultas)

Template Tags

En HTML no podemos poner código Python, ya que los navegadores sólo interpretan HTML. Por otra parte, HTML es un lenguaje estático, mientras que Python es dinámico, por lo tanto, Django implementa los template tags, estos nos permiten transferir cosas de Python como cosas en HTML.


Funcionamiento del MTV de Django


Bibliografía

1. Django: Hello World - MVC - 2016. (2016). Bogotobogo.com. Retrieved 11 October 2016, from http://www.bogotobogo.com/python/Django/Python_Django_MVC_Model_View_Controller_Framework.php

2. FAQ: General | Django documentation | Django. (2016). Docs.djangoproject.com. Retrieved 11 October 2016, from https://docs.djangoproject.com/es/1.10/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names

3. Definiendo nuevos tipos (Algoritmos de Programación con Python). (2016). Librosweb.es. Retrieved 11 October 2016, from http://librosweb.es/libro/algoritmos_python/capitulo_14/definiendo_nuevos_tipos.html

4. Model field reference | Django documentation | Django. (2016). Docs.djangoproject.com. Retrieved 13 October 2016, from https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-options

5. Model field reference | Django documentation | Django. (2016). Docs.djangoproject.com. Retrieved 13 October 2016, from https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types

6. Model field reference | Django documentation | Django. (2016). Docs.djangoproject.com. Retrieved 13 October 2016, from https://docs.djangoproject.com/en/1.8/ref/models/fields/#module-django.db.models.fields.related

7. Model field reference | Django documentation | Django. (2016). Docs.djangoproject.com. Retrieved 13 October 2016, from https://docs.djangoproject.com/en/1.8/ref/models/fields/#attributes-for-fields

8. Model instance reference | Django documentation | Django. (2016). Docs.djangoproject.com. Retrieved 14 October 2016, from https://docs.djangoproject.com/en/1.8/ref/models/instances/

9. Django ORM (Querysets) · Django Girls Tutorial. (2016). Tutorial.djangogirls.org. Retrieved 13 October 2016, from https://tutorial.djangogirls.org/en/django_orm/

10. QuerySet API reference | Django documentation | Django. (2016). Docs.djangoproject.com. Retrieved 13 October 2016, from https://docs.djangoproject.com/en/1.8/ref/models/querysets/

RESTful APIs en Ruby on Rails

Llevado a Uds por el

Grupo 12
  • Fabián Da Silva
  • Felipe Mancilla
  • Nestor Venegas

El desarrollo de un RESTful API basado en RoR, se trabajara de tres formas:

  1. Forma Manual
  2. Usando Gemas(“Rails-api”):
    • En Rails 5
    • Rails con versión < 5


Forma Manual

Los pasos a seguir son:

Primero se crea un nuevo Proyecto

   rails new api

Generamos el modelo, controlador y las vistas respectivas para el modelo "Usuario".

   rails generate scaffold User username:string password:string

Por defecto se creará el modelo y agrega dos atributos más, “create_at” y “updated_at”.

UserDB.png


Mapeamos el modelo en la base de datos.

   rake db:migrate.

Como es una RESTful API, no necesitamos a las vistas html que fueron creadas, por lo que se borran (Solo necesitaremos las vistas .json.jbuilder).

Jbuilder.png

Vamos a nuestro controlador, y modificamos para que solo nos entregue en forma json. Controller.png Controllerjson.png


Y así con todas las acciones que involucren el "format.html"


Para crear url’s existentes que coincidan con nuestro UsuarioController, requerimos ir a config/routes.rb y setear lo sgte:

       Rails.application.routes.draw do 
       resources :users 
       end

Routes.png

Para el error de “Invalid Authenticity Token” (Maniobra anti-hacking “CSRF attack”). Pasamos a nuestro controlador "application_controller" y cambiamos lo sgte:

       Protect_from_forgery with: :null_session

AppControler.png

Probamos validaciones para que no se guarden datos nulos.

UserModel.png

Como podemos ver, no se ven los atributos del modelo “Usuario”, porque revisamos las vistas no eliminadas (.json.jbuilder).

Podemos observar que entrega un arreglo json, pero cada elemento lo renderiza en una vista llamada “_user.json.jbuilder” (Ahí hay que hacer los cambios).

UserJson.png

Postman.png


Finalmente podemos crear un usuario, y hay que hacer lo mismo con actualizar y borrar usuarios.

PostUser.png


Usando Gemas “Rails-api”.

Rails 5

Esta gema viene instalada en Rails 5, por lo que no es necesario incluirla en nuestro “GemFile”. Para versiones de Rails anteriores al 5, se instala la gema.

GemRails.png

Para el caso de usar Rails 5, se genera un nuevo proyecto "RESTful API" con el sgte comando:

        rails new proy_api --api

A diferencia de la forma general en que se crea un proyecto, este comando hace que generar cualquier componente (Modelo, Controlador, etc) y en estas incluyan las vistas, se generen solo las vistas "JSON" (json.jbuilder).

Pero antes es necesario chequear que este instalado la gema "Jbuilder". GemJbuilder.png

Con esto el framework setea todo lo que hicimos de forma manual en cada comando que aplicamos. (Por ej: rails g scaffold Post title:string description:string).

Post.png

Rails Versión < 5

Para versiones anteriores del Rails (4.x.x o menos), se instala la gema (gem install rails-api) y para crear un proyecto se usa el comando:

       rails-api new [NombreApp]

Luego para crear modelos, vistas, controladores, etc. Se utiliza el mismo comando “rails” que conocemos.

       rails g scaffold Usuario [atributos]:[Tipo de Dato]

RESTful APIs en Django

Grupo 8
  • Yerson Escobar
  • Jonathan Galassi
  • Cristóbal Galleguillos


Para la implementación de REST en Django se utilizará un paquete llamado Djangorestframework.

Ventajas

  • Políticas de autenticidad para OAuth1a y OAuth2.
  • Serialización de tipos de datos ORM y no ORM.
  • Fácil de modificar si no se requieren otras funciones.
  • Posee una documentación extensa y una gran comunidad
  • Es usado y confiado por distintas compañías como Mozilla, RedHat, Heroku, entre otros.

Prerrequisitos

  • Python 2.7 o 3.2+
  • Django 1.8+

Pasos para la configuración he instalación

Paso1.jpg

Hasta ahora solo hemos instalado todo lo necesario en un entorno virtual.


Ahora crearemos un proyecto, ejecutaremos las migraciones y crearemos una app de ejemplo.

Paso2.jpg


Para configurar Django Rest Framework abrimos el archivo settings.py y añadimos lo siguiente.

Paso3.jpg

Primero añadimos nuestra app y después rest_framework, más abajo, decimos que las peticiones solo podrán ser procesadas cuando el usuario sea admin y nuestra api devolverá para cada petición 10 resultados que irán paginados con ?page=1 (devolverá los 10 primeros) etc, más información acerca de permisos.


Ahora necesitamos crear un archivo llamado serializers.py dentro de restapp, aquí será donde representemos los datos que queremos devolver a través de la api, de momento vamos a utilizar lo que viene con Django por defecto.

Paso2,5.jpg

De esta forma le decimos a nuestra api que para el modelo User devuelva los campos url, username, email y groups para el model User, este último son los grupos a los que pertenece un usuario.


Ahora debemos crear el punto de resolución de nuestra api que será el archivo views.py de nuestra app restapp, así que abre el archivo y modifica el código por el siguiente.

Paso4.jpg

Simplemente debemos definir dos cosas, queryset, para decir que queremos devolver, y la clase que se encarga de representar los datos en cada caso, nada más.


Ahora vamos a modificar el archivo de urls para tener acceso a nuestra api.

Paso5.jpg


También existe la posibilidad de especificar permisos para cada url, por ejemplo, podemos modificar la clase UserViewSet para que sólo puedan acceder los usuarios que se hayan identificado previamente.

Paso6.jpg

Herramientas de gestión de proyectos

Grupo 13
  • Laura Bermeo
  • Renata Mella
  • Ian Zamorano

Algunas herramientas

Cuando se trabaja en equipo sobre un proyecto, es útil contar con ciertas herramientas que resuelvan el problema de organización y planificación, junto con facilitar instancias en donde los integrantes del equipo trabajan al mismo tiempo pero no necesariamente en el mismo lugar. Se presentarán las siguientes herramientas: Trello, un gestor de tareas para el trabajo colaborativo; Slack, una aplicación de mensajería para equipos; JIRA, una herramienta para bug tracking, issue tracking y gestión de proyectos.

Trello

Trello [17] es un gestor de tareas pensado para el trabajo colaborativo. Tiene tableros como elementos centrales y columnas con notas. Está basado en kanban para organizar el estado de las tareas.

Trello.png

Características

  • Ofrece notas, listas, comentarios, notificaciones, calendario además de adjuntar imágenes y archivos.
  • Integración con múltiples herramientas de trabajos (como Calendar, Dropbox, Drive, GitHub, Twitter, Evernote entre otros).

Ventajas

  • Es sencillo de usar, solo es necesario familiarizarse con elementos como el tablero y columnas para editar; las notas y opciones adicionales son similares en otras herramientas.
  • Posee una aplicación móvil, donde puedes visualizar y editar sin necesidad de entrar al computador.
  • Tiene una versión gratuita.

Desventajas

  • No tiene un sistema de chat entre los miembros.
  • La versión pagada es bastante cara ($50 USD mensual por equipo).
  • La versión gratis suele servir solo en trabajos pequeños.

Algunas empresas que utilizan esta herramienta

Slack

Slack [20] es una aplicación de mensajería de escritorio y móvil para equipos. Junta toda la comunicación y archivos del equipo en un solo lugar.

Slack.png

Características

  • Es un sistema de mensajería.
  • Incluye integración con diversas herramientas de trabajo (como Dropbox, GitHub, Twitter, entre otros).
  • Organiza las conversaciones en canales.
  • Está la opción de crear salas de chat privadas con acceso permitido solo a miembros elegidos.
  • Existe la versión gratis, estándar (USD$6.67 por mes por miembro) y plus (USD$12.50 por mes por miembro).

Ventajas

  • Se pueden compartir archivos y realizar una búsqueda tanto en sus títulos como en sus contenidos.
  • Comunicación inter-organizacional.
  • Entrega orden y disciplina gracias a la separación por canales.
  • Se tiene acceso a los mensajes y archivos aun estando offline.
  • Existen múltiples aplicaciones y bots disponibles para integrar a Slack.

Desventajas

  • No tiene sistema de recordatorios; para ello se debe usar la integración de aplicaciones y elegir alguna externa a Slack.
  • La versión gratis tiene muchas limitaciones (hasta 5GB de almacenamiento por equipo, falta de llamadas grupales, solo guarda hasta 10.000 mensajes antiguos, entre otros).
  • Hay que tener cuidado de mantener el orden y no recargar de canales al equipo.

Algunas empresas que utilizan esta herramienta

  • IceCube Collaboration [21]
  • charity: water [22]
  • El equipo tras el explorador de Marte, Curiosity [23]

JIRA

JIRA [24] es una herramienta desarrollada por la compañía australiana Atlassian. Es utilizada para bug tracking, issue tracking y gestión de proyectos.

JIRA.png

Características

  • Incluye tableros Scrums y tableros Kanban.
  • Reportes Ágiles.
  • Admite planeación de Portafolios.
  • Gestión de Proyectos.

Ventajas

  • Se adapta a los diferentes métodos de desarrollo que existen en el ámbito del desarrollo de software.
  • Tiene una herramienta llamada Confluence, donde se pueden tomar notas de una reunión, agregar requerimientos de un producto, registrar decisiones, crear un blog con noticias, hacer retrospectivas del trabajo, entre otras cosas.
  • La gestión de personal (confluence) está separada de la gestión de proyectos (JIRA).
  • Existe gran variedad de herramientas para integrar junto a JIRA.

Desventajas

  • Es complicado de utilizar para un usuario nuevo.
  • Es pagada. Su valor es de $10 USD para equipos de hasta 10 personas y $75 USD para equipos de 15 integrantes. Tiene una prueba gratis de 7 días.
  • La integración con otras aplicaciones es pagada (el precio varía según la aplicación).

Algunas empresas que utilizan esta herramienta



JSON web tokens (JWT

Grupo 11
  • Sergio Herrera
  • Inti Pontt

¿Qué es JWT (JSON Web Token)?

-Es un estándar de autenticación basado en JSON -Lo podemos utilizar en muchos lenguajes Ruby, Elixir, Node.js, Python, PHP, .NET, Java, Clojure, ClojureScript, etc. -Patrocinado por grandes empresas del sector tecnológico (como Google, Microsoft, Facebook, etc). -En simples palabras, toma un conjunto de datos json y los encripta para ser transmitidos como una cadena de caracteres encriptados.

Formato token JWT

3 cadenas de caracteres separados por un punto.

  • Header: Cabecera del token, compuesta de 2 partes
  1. Tipo (en este caso JWT)
  2. Codificación utilizada (Comúnmente es el algoritmo HMAC SHA256)
Ejemplo de cabecera sin codificar
{
    “alg”: “HS256”,
    “typ”: “JWT”
}
Luego de codificar, es la primera parte de la cadena antes del punto:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  • Payload: aqui van los atributos que definen al token. Los más comunes a utilizar son:
    • sub: Identifica el sujeto del token, por ejemplo un identificador de usuario.
    • iat: Identifica la fecha de creación del token, válido para si queremos ponerle una fecha de caducidad. En formato de tiempo UNIX
    • exp: Identifica a la fecha de expiración del token. Podemos calcularla a partir del iat. También en formato de tiempo UNIX.
  • Signature:
Esta firma está formada por los anteriores componentes (Header y Payload) cifrados en Base64 con una clave secreta (un secreto almacenada en nuestro servidor). Así sirve de Hash para comprobar que todo está bien.

Podemos jugar a crear nuestros propios token en la siguiente página https://jwt.io/

¿Por qué utilizar JWT?

La mayoría de las aplicaciones actuales consumen servicios rest y están alojadas en distintos dominios con lo cuál no podemos trabajar con sesiones ya que se almacenan en este.

Podemos decir que la mejor alternativa es llevar a cabo la autenticación haciendo uso de tokens que vayan del servidor al cliente, un usuario hace login (no necesita enviar token porque no lo tiene), una vez el servidor de ok retorna un token cómo respuesta y el usuario debe enviar dicho token en las siguientes peticiones para poder acceder a los recursos del servicio.

En cada petición el servidor debe comprobar el token proporcionado por el usuario y si es correcto podrá acceder a los recursos solicitados, de otra forma deberá denegar la petición.

También nos añade más seguridad. Al no utilizar cookies para almacenar la información del usuario, podemos evitar ataques CSRF (Cross-Site Request Forgery) que manipulen la sesión que se envía al backend. Por supuesto podemos hacer que el token expire después de un tiempo lo que le añade una capa extra de seguridad.

Flujo tipico

  1. El Usuario ingresa sus credenciales.
  2. En el Servidor son verificadas contra un almacenamiento o servicio, pero en lugar de crear una sesión y retornar un cookie, retornará un objeto JSON que contiene un JWT.
  3. El Cliente recibe el objeto JSON con el JWT y es almacenado. Normalmente en el almacenamiento local.
  4. Este JWT almacenado es enviado por el Cliente al Servidor para acceder a rutas protegidas.
  5. El Servidor en el API espera y chequea un JWT válido y si hay uno, procederán la petición y retornará la respuesta esperada.
  • Dado que la información del usuario está contenida dentro del JWT, no hay necesidad de validar el usuario en la Base de Datos, lo cual disminuye la latencia de la aplicación.
  • Resaltaremos que el estado del usuario nunca es almacenado en la memoria del servidor, lo cual significa que el usuario no está autenticado en el sentido tradicional. Sin embargo, un JWT válido le da al usuario la llave para acceder a los datos cada vez que hace una petición, de esta manera es implementada la autenticación sin estado.

Jwt-flujo.jpg

¿Por qué utilizar JWT sobre SWT (Simple Web Tokens) y SAML (Security Assertion Markup Language Tokens)?

Hablemos de las ventajas de JSON Web Tokens (JWT) comparándolo con Tokens Web Simple (SWT) y Security Assertion Markup Language Tokens (SAML).

  • Como JSON es menos detallado que XML, cuando está codificado, su tamaño también es más pequeño; Haciendo JWT más compacto que SAML. Esto hace que JWT sea una buena opción para pasar en entornos HTML y HTTP.
  • En cuanto a la seguridad, SWT sólo puede ser firmado utilizando el algoritmo HMAC. Mientras que los tokens JWT y SAML también pueden usar un par de claves públicas/privadas en forma de un certificado X.509 para firmarlos. Sin embargo, la firma de XML con XML Digital Signature es muy difícil en comparación con la simplicidad de la firma de JSON.
  • Los analizadores JSON son comunes en la mayoría de los lenguajes de programación, ya que se asignan directamente a los objetos; por el contrario, XML no tiene una asignación de documento a objeto natural. Esto hace que sea más fácil trabajar con JWT que las aserciones de SAML.
  • En cuanto al uso, JWT se utiliza en una escala de Internet. Esto pone de relieve la facilidad de procesamiento del lado del cliente de JWTs en múltiples plataformas, especialmente móviles.

¿Cómo usamos JSON Web Tokens en Oauth?

En Oauth, emitimos JWTs como resultado del proceso de autenticación. Cuando el usuario inicia sesión con Oauth, se crea un JWT, se firma y se envía al usuario. Oauth soporta la firma de JWT con algoritmos HMAC y RSA. Este símbolo se utilizará entonces para autenticar y autorizar con API que otorgarán acceso a sus rutas y recursos protegidos.

También usamos JWTs para realizar autenticación y autorización en la API v2 de Oauth, reemplazando el uso tradicional de las claves API opacas regulares. En cuanto a la autorización, JSON Web Tokens permite la seguridad granular, que es la capacidad de especificar un determinado conjunto de permisos en el token, lo que mejora la depuración.

JWT vs Oauth2

  • Manzanas y naranjas
  • Lo más importante a entender al comparar JWT y OAuth2, es que no son iguales. O incluso incompatibles.
  • JWT es un protocolo de autenticación
  • Esto significa que es un conjunto estricto de instrucciones para la emisión y validación de tokens de acceso firmadas. Los tokens contienen declaraciones que son utilizadas por una aplicación para limitar el acceso a un usuario.
  • OAuth2 es un framework de autenticación
  • OAuth2 por otro lado es un framework, se piensa como un lineamiento muy detallado, para permitir que los usuarios y las aplicaciones autoricen permisos específicos a otras aplicaciones en ambientes tanto privados como públicos.
  • ¿Qué pasa con el 'VS' en el título?
  • Así que necesito aclararme. La única razón por la que se pone 'vs' en el título fue porque muchas personas buscan una comparación útil, y probablemente la buscará así.
  • El 'vs' en el título es engañoso, como se mencionó, los dos no son incompatibles entre sí. Es posible tener una implementación OAuth2 que emita JSON Web Tokens como un mecanismo de autenticación.
  • Así que antes de que podamos tomar una decisión sobre qué implementar necesitamos entender exactamente lo que esta solución nos puede proporcionar.
  • ¿Qué es JSON Web Tokens?
  • JSON Web Token (JWT) es un medio compacto y seguro para URL que representa las credenciales que se van a transferir entre dos partes. Las credenciales en un JWT se codifican como un objeto JSON que se firma digitalmente usando JSON Web Signature (JWS).
  • ¿Qué es OAuth2?
  • OAuth2, alternativamente, no es un protocolo es un framework de seguridad. Se detalla cómo múltiples funciones diferentes, los usuarios de su sistema, las aplicaciones del lado del servidor como una API y los clientes, como sitios web o aplicaciones móviles nativas, pueden autenticarse entre sí.
  • Ambos aplicaciones y usuarios pueden ser:
  1. Resource Owner
  2. Resource Server
  3. Client Application
  4. Authorization Server
  • ¿Un caballo diseñado por un comité?
OAuth2 es una especificación bastante masiva.
El comité, que creó OAuth2, la intención inicial fue hacer un estricto protocolo estándar. Sin embargo, el comité no pudo llegar a un consenso sobre partes importantes del proyecto, por lo que ni siquiera alcanzó ese nivel.
  • Protección de la contraseña de usuario: ¡Necesita HTTPS!
  • Antes de entrar en cualquier discusión sobre la implementación de OAuth2 y JWT, vale la pena tomar un momento para señalar que ambas soluciones requieren seguridad SSL (https). Esto cifra los datos que se envían a lo largo del cable, es decir, desde el navegador hasta el servidor.
  • Esto es crucial porque ninguna de las soluciones proporciona una forma de mantener secretas las credenciales suministradas por el usuario cuando está en tránsito. Esto significa que cualquier persona snooping en una conexión wifi interna podría intercectar su nombre de usuario y contraseña, cuando lo envían durante el inicio de sesión!
  • Conclusión
  • JWT
  • La principal ventaja de JWT es que maneja la sesión de usuario de su aplicación de forma escalable sin estado. El uso de reclamaciones incrustadas significa que podemos extraer fácilmente información de sesión de usuario en un servidor que no tiene acceso a la base de datos de usuario/sesión de su sistema. Para una Arquitectura Orientada a Servicios distribuida esto puede ser tremendamente útil.
  • La desventaja es que si se implementan mecanismos de actualización de token de larga duración con listas negras de tokens, se pierde un poco de la promesa de ahorrarse un dolor de cabeza en la implementación.
  • fortalezas
  1. Rápido tiempo de desarrollo
  2. No necesita cookies
  3. JSON es un formato amigable para móviles
  4. No hay dependencia de inicio de sesión social
  5. Comprensión conceptual relativamente simple
  • Limitaciones clave
  1. Los tokens tienen límite de tamaño.
  2. Los tokens no pueden ser revocados.
  3. Esto requiere que los tokens tengan una expiración corta.
  • Oauth2
  • Externalizar su servidor de autenticación
Como se discutió en la consideración de la implementación, si no le importa que su API tenga una dependencia de un proveedor de autenticación de terceros, simplemente puede subcontratar su servidor de autenticación.
Usted registra su aplicación con un proveedor, detallando qué acceso necesita de su usuario, como su dirección de correo electrónico, nombre, etc.
Cuando el usuario aterrice en su sitio, verán botones en su página de registro para que se conecten con el proveedor de su elección. El usuario será redirigido de su sitio a su proveedor, se le pedirá que permita que su aplicación acceda a su cuenta, y luego se le redirigirá de nuevo a su sitio web.
  • fortalezas
  1. Rápido tiempo de desarrollo
  2. Pequeña cantidad de código para implementar
  3. Mantenimiento reducido
  • Solución para grandes empresas
Si tiene muchas API que necesitan autenticación con diferentes tipos de aplicaciones, tanto en entornos públicos como privados, la implementación OAuth 2 probablemente tenga sentido.
Esto requerirá un equipo pequeño y horas dedicadas considerables, pero resultará en una seguridad completa y flexible para sus muchas aplicaciones diferentes. Se advirtió que es mas complicado para implementar.
  • Recomendación Final
  • Si ya ha implementado tokens web JSON, puede utilizarlos como sus bearer tokens con las reivindicaciones que proporcionan los detalles de los ámbitos de autorización en su configuración de OAuth2.

Configuración de una autenticación basada en tokens con Rails 5

  • Creamos una api
rails new jwt --api
  • Hay varios requisitos que deben cumplirse antes de poder utilizar el enfoque basado en tokens:
  1. Necesitamos un modelo accesible.
  2. Se debe implementar una forma de codificar y decodificar tokens JWT.
  3. Necesitamos métodos para comprobar si el usuario está autenticado.
  4. Los controladores para crear y registrar usuarios también son necesarios.
  5. Necesitamos rutas para crear usuarios y registrarlos dentro y fuera.
Creamos el modelo users
  • rails g model User name email password_digest
  • Corremos las migrations:
rails db:migrate
  • Al ejecutar estos métodos, creamos un modelo de usuario con campos de nombre, correo electrónico y contraseña y hemos migrado su esquema en la base de datos.
  • El método has_secure_password debe añadirse al modelo para asegurarse de que la contraseña esté correctamente encriptada en la base de datos: has_secure_password forma parte de la gema bcrypt, por lo que tenemos que instalarla primero. Añadir al gemfile:
#Gemfile.rb
gem 'bcrypt'
  • Instalamos:
bundle install
  • Con la gema instalada, el método se puede incluir en el modelo:
#app/user.rb
class User < ApplicationRecord
has_secure_password
end
Codificación y decodificación de tokens JWT
  • Una vez finalizado el modelo de usuario, puede iniciarse la implementación de la generación de token JWT. En primer lugar, la gema jwt hará la codificación y decodificación de tokens HMACSHA256 disponibles en la aplicación Rails. Vamos a instalarlo:
gem 'jwt'
  • instalamos
bundle install
  • Una vez instalada la gema, se puede acceder a ella a través de la variable global JWT. Debido a que los métodos que se van a utilizar requieren encapsulación, una clase singleton es una gran manera de envolver la lógica y utilizarla en otras construcciones.
  • Para aquellos que no están familiarizados, una clase singleton restringe la instanciación de una clase a un solo objeto, lo que resulta útil cuando sólo se necesita un objeto para completar las tareas a mano.
# lib/json_web_token.rb
class JsonWebToken
class << self
def encode(payload, exp = 24.hours.from_now)
payload[:exp] = exp.to_i
JWT.encode(payload, Rails.application.secrets.secret_key_base)
end
def decode(token)
body = JWT.decode(token, Rails.application.secrets.secret_key_base)[0]
HashWithIndifferentAccess.new body
rescue
nil
end
end
end
  • El primer método, encode, toma tres parámetros: el identificador de usuario, el tiempo de caducidad (1 día) y la clave base única de la aplicación Rails, para crear un token único.
  • El segundo método, decode toma el token y utiliza la clave secreta de la aplicación para decodificarlo.
  • Estos son los dos casos en que se utilizarán estos métodos:
Para autenticar al usuario y generar un token para el usuario usando encode
Para comprobar si el token del usuario agregado en cada solicitud es correcto utilizando decode.
  • Para asegurarse de que todo funciona, el contenido del directorio lib debe ser incluido cuando se carga la aplicación Rails:
#config/application.rb
module ApiApp
class Application < Rails::Application
#.....
config.autoload_paths << Rails.root.join('lib')
#.....
end
end


Autenticación de usuarios
  • En lugar de usar métodos de controladores privados, se puede usar simple_command
  • La gema simple_comand es una forma fácil de crear servicios. Su papel es similar al papel de un ayudante, pero en lugar de facilitar la conexión entre el controlador y la vista, hace lo mismo para el controlador y el modelo. De esta manera, podemos acortar el código en los modelos y controladores.
  • Add the gem to your Gemfile:
gem 'simple_command'
  • And bundle it:
bundle install
  • A continuación, el alias de los métodos de simple_command pueden usarse fácilmente en una clase escribiendo Preced SimpleCommand. Aquí está cómo se estructura el comando:
class AuthenticateUser
prepend SimpleCommand
def initialize()
#Parametros que tomara cuando es llamado el comando
end
def call
#aqui el resultado que devolverá
end
end
  • El comando tiene que tomar el correo electrónico y la contraseña del usuario y devolver al usuario si las credenciales coinciden.
  • Nos quedaría asi:
# app/commands/authenticate_user.rb
class AuthenticateUser
prepend SimpleCommand
def initialize(email, password)
@email = email
@password = password
end
def call
JsonWebToken.encode(user_id: user.id) if user
end
private
attr_accessor :email, :password
def user
user = User.find_by_email(email)
return user if user && user.authenticate(password)
errors.add :user_authentication, 'invalid credentials'
nil
end
end
  • El comando toma los parámetros e inicializa una instancia de clase con atributos de correo electrónico y contraseña accesibles dentro de la clase. El usuario del método privado utiliza las credenciales para comprobar si el usuario existe en la base de datos utilizando User.find_by_email.
  • Si se encuentra el usuario, el método utiliza el método de autenticación incorporado (disponible poniendo has_secure_password en el modelo de usuario para comprobar si la contraseña del usuario es correcta), si todo es verdad, se devolverá el usuario. Return nil.
Chequeando la autorización del usuario
  • La creación de token se realiza, pero no hay manera de comprobar si un token que se ha agregado a una solicitud es válido. El comando de autorización tiene que tomar los encabezados de la solicitud y decodificar el token utilizando el método decode en el singleton JsonWebToken.
  • Estructura del codigo
# app/commands/authorize_api_request.rb
class AuthorizeApiRequest
prepend SimpleCommand
def initialize(headers = {})
@headers = headers
end
def call
user
end
private
attr_reader :headers
def user
@user ||= User.find(decoded_auth_token[:user_id]) if decoded_auth_token
@user || errors.add(:token, 'Invalid token') && nil
end
def decoded_auth_token
@decoded_auth_token ||= JsonWebToken.decode(http_auth_header)
end
def http_auth_header
if headers['Authorization'].present?
return headers['Authorization'].split(' ').last
else
errors.add(:token, 'Missing token')
end
nil
end
end
  • Este código ejecuta una cadena de métodos. Vamos de abajo hacia arriba.
El último método de la cadena, http_auth_header, extrae el token del encabezado de autorización recibido en la inicialización de la clase. El segundo método de la cadena es decoded_auth_token, que decodifica el token recibido de http_auth_header y recupera el ID del usuario.
  • La lógica en el método de usuario puede parecer abstracta, así que vamos a pasar por ella línea por línea.
En la primera línea, el operador || = se utiliza para asignar @user asignando "if not nil". Básicamente, si el User.find () devuelve un conjunto vacío o decoded_auth_token devuelve false, @user será nil.
Pasando a la segunda línea, el método de usuario devolverá al usuario o lanzará un error. En Ruby, la última línea de la función se devuelve implícitamente, por lo que el comando termina devolviendo el objeto de usuario.
Implementación de métodos auxiliares en los controladores
  • Toda la lógica para el manejo de tokens JWT ha sido establecida. Es hora de implementarlo en los controladores y ponerlo al uso real. Las dos piezas más esenciales a implementar son la identificación de usuario de inicio de sesión y la referencia del usuario actual (current_user).
  • Primero, comencemos con el inicio de sesión del usuario:
# app/controllers/authentication_controller.rb
class AuthenticationController < ApplicationController
skip_before_action :authenticate_request
def authenticate
command = AuthenticateUser.call(params[:email], params[:password])
if command.success?
render json: { auth_token: command.result }
else
render json: { error: command.errors }, status: :unauthorized
end
end
end
  • La acción de autenticación tomará los parámetros JSON para el correo electrónico y la contraseña a través del hash de params y los pasará al comando AuthenticateUser. Si el comando tiene éxito, enviará el token JWT de nuevo al usuario.
  • Agregamos la ruta
#config/routes.rb
post 'authenticate', to: 'authentication#authenticate'
  • Solicitudes de autorización
Para que el token se use, debe existir un método current_user que "persista" al usuario. Para que current_user esté disponible para todos los controladores, debe declararse en el ApplicationController:
  1. app/controllers/application_controller.rb
class ApplicationController < ActionController::API
before_action :authenticate_request
attr_reader :current_user
private
def authenticate_request
@current_user = AuthorizeApiRequest.call(request.headers).result
render json: { error: 'Not Authorized' }, status: 401 unless @current_user
end
end
Mediante el uso de before_action, el servidor pasa los encabezados de solicitud (utilizando la propiedad de objeto incorporada request.headers) a AuthorizeApiRequest cada vez que el usuario hace una solicitud. Los resultados de la solicitud se devuelven al @current_user, quedando así disponibles para todos los controladores que heredan de ApplicationController.
Ahora probaremos
  • Para estas pruebas crearemos unos usuarios de prueba
User.create!(email: 'usuario1@mail.com' , password: '12345678' , password_confirmation: '12345678')
  • Para ver cómo funciona la autorización, es necesario que haya un recurso que debe solicitarse.
rails g scaffold Note name:string description:text
  • Esto creará un recurso denominado Note de arriba a abajo - un modelo, un controlador, rutas y vistas. Migrar la base de datos:
rake db:migrate
  • Ahora probamos mediante postman
Metodo POST http://localhost:8080/authenticate
Body Content-Type: application/json:
{"email":"usuario1@mail.com","password":"12345678"}
{
"auth_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE0ODA2MzQ2MzR9.P0qTHnlPBcQuwRj_zC0zhJ8XAvRru6mQbJuOsKBhT40"
}
Metodo GET http://localhost:8080/notes
{
"error": "Not Authorized"
}
Metodo GET http://localhost:8080/notes
Headers
Content-Type ---->application/json
Authorization ---->Token
[]



IONIC

  • Pamela González
  • Barbarita Lara
  • Jonathan Tapia

Ionic es una herramienta gratuita open source, para el desarrollo de aplicaciones híbridas basadas en HTML5, CSS y JS. Está construido básicamente en Angular utilizando apache Cordova y el preprocesador de CSS, SASS La principal característica de ionic radica en el desarrollo de aplicaciones híbridas, es decir poder desarrollar solo una aplicación que pueda correr en Android, iOS y Windows phone.

Personalización y diseño responsive

Como la interfaz de usuario que por defecto facilita Ionic es prácticamente HTML5 en su estado más puro, la personalización de ésta se realiza mediante SASS, el cual está basado en ruby y permite crear hojas de estilos estructuradas, limpias y fáciles de mantener. Junto con las librerías propias que incorpora Ionic, posee más de 450 iconos y símbolos de código abierto para su libre uso, además posee capacidad responsive design así se adapta el contenido al tamaño de la pantalla o densidad de píxeles extendiendo aún más la capacidad de personalización.

Widgets

Los componentes de Ionic son tremendamente simples. Se trata de elementos HTML personalizados que incorporan controladores para complementar configuración e interacción. A diferencia de otros framework donde podemos encontrar widgets más complejos, Ionic ofrece bloques de código más simples y orientados a que sean combinados para ofrecer una interfaz de usuario más rica, intuitiva y atractiva para el público receptor.

Creando una app básica en ionic

  • Se requiere previamente la instalación de node.js[30], el cual es básicamente un programa de servidor que por medio del motor v8 de javascript permite múltiples conexiones en el servidor sin colapsarlo.
  • Utilizando node instalamos ionic y cordova junto a sus respectivas lineas de comandos:
npm install -g cordova ionic
  • Creamos una myApp como aplicación nueva e utilizamos un template en blanco:
ionic start --v2 myApp blank
Templates.png


  • Iniciamos la aplicación mediante el browser (localhost:8100):
cd myApp ionic serve


Blank template.png


  • Para agregar la compatibilidad con Android[31] y iOS[32]:
ionic platform add android
ionic platform add ios
  • Luego con el comando siguiente podemos ver en nuestro browser:
ionic serve --lab


IOS android.png


  • Finalmente se tienen las siguientes carpetas en la nueva aplicación:
Folders.png


Angular

AngularJS es un framework JavaScript creado y mantenido por Google que es utilizado para la creación de aplicaciones web siguiendo el patrón Modelo Vista Controlador, capacitado para extender nuestros documentos HTML añadiendo nuevas etiquetas y atributos que cumplirán con funciones específicas ya definidas o programadas por el desarrollador.

  • Con AngularJS permite un código JavaScript organizado.
  • Es compatible con JQuery y otras librerías.
  • Facilidad para hacer tests.

Control DOM

AngularJS incluye jqLite, una pequeña versión ultraligera de jQuery que permite la gestión de DOM (Document Object Model, Modelo de Objetos del Documento) de forma compatible en la inmensa mayoría de navegadores, dejando una pequeñísima huella en los mismos haciendo la app mucho más ligera y eficiente. Por supuesto, si con jqLite no tuviésemos suficiente, podremos implementar una funcionalidad extendida cargando jQuery con el documento, con la consecuente pérdida de velocidad.

Cordova

Apache Cordova es un marco de desarrollo móvil de código abierto. Permite utilizar las tecnologías estándar web como HTML5, CSS3 y JavaScript para desarrollo multiplataforma, evitando el lenguaje de desarrollo nativo cada plataformas móviles. Aplicaciones ejecutan dentro de envolturas para cada plataforma y dependen de enlaces estándares API para acceder a de cada dispositivo sensores, datos y estado de la red.

Cordova arqui.png


Apache Cordova aplicaciones se basan en un común config.xml archivo que proporciona información acerca de la aplicación y especifica los parámetros que afectan a cómo funciona, como si responde a la orientación cambia de puesto. Este archivo se adhiere a la especificación de Empaquetado de la aplicación Web, widget, o de la W3C. La misma aplicación se implementa como una página web, un archivo local llamado index.html, que hace referencia a cualquier CSS, JavaScript, imágenes, archivos multimedia u otros recursos son necesarios para que se ejecute de forma predeterminada. La aplicación se ejecuta como un WebView dentro de la envoltura de la aplicación nativa, que distribuye a tiendas de aplicaciones. Una interfaz plugin está disponible para Cordova y componentes nativos para comunicarse con los demás. Esto te permite invocar un código de JavaScript. Idealmente, las API de JavaScript para ese código nativo son consistentes a través de múltiples plataformas de dispositivos.


Gulp

Se trata de un automatizador te permite evitar lidiar con procesos de trabajo mecánicos, no importa que seas back-end o front-end, para los desarrolladores les permite la reducción de código JavaScript, recarga del navegador, compresión de imágenes, validación de sintaxis de código, etc. Gulp.js está construído con Javascript, funciona sobre Node.js y es Open Source [33].


Bibliografía

  1. Documentacion oficial Ionic, http://ionicframework.com/docs/
  2. Documentacion oficial Cordova, https://cordova.apache.org/docs/en/latest/
  3. Primeros pasos Gulp, http://dazzet.co/tutorial-de-gulp/
Sitios de interés

OpenID Connect

Grupo 15
  • Matías Yañez
  • Eduardo Vera

Existe la necesidad en muchas aplicaciones de identificar a sus usuarios. Debido a que tener un sistema local de autentificación se vuelve un problema a medida que la cantidad de usuarios crece, es que la solución es delegar la autentificación de usuarios a un servicio externo dedicado llamado Identity Provider (IdP). OpenID Connect es un estándar para IdPs que presenta varias ventajas:

  1. Identity Tokens de fácil consumo:: Las aplicaciones cliente reciben la identidad del usuario codificada en una Jason Web Token(JWT), que llamamos Identity Token(ID Token). JWT tiene soporte para firmas y encriptación.
  2. Basado en el protocolo OAUTH 2.0: Las aplicaciones cliente usan flujos de OAUTH 2.0 para obtener ID tokens, que soportan aplicaciones web, nativas y móviles. OAUTH 2.0 también significa usar un sólo protocolo para la autentificación y autorización de Access tokens.
  3. Simplicidad: OpenID Connect es lo suficientemente simple para integrarse a aplicaciones básicas, pero tiene suficientes herramientas para escalar a aplicaciones complejas.

Identity tokens

Una ID Token es análoga al concepto de una cédula de identidad, en formato JWT, y firmada por un OpenID Provider (OP). Para obtener una, la aplicación cliente debe mandar al usuario a su OP con una petición de autentificación. Veamos un ejemplo de una ID Token empacada como un objeto JSON:

ID Token en formato JSON

Características de una ID Token:

  1. La identidad del usuario, llamado subject en OpenID(sub).
  2. Especifica la autoridad que emite el certificado(iss).
  3. Es generada para un cliente en particular, llamado audiencia(aud).
  4. Puede contener un nonce(nonce).
  5. Puede especificar cuándo(auth_time) y cómo, en términos de permisos(acr), se autentificó al usuario.
  6. Tiene una fecha de emisión(iat) y de expiración(exp).
  7. Puede incluir detalles adicionales sobre el usuario, tales como nombre y email.
  8. Está firmada digitalmente, para que pueda ser verificada por los receptores.
  9. Puede ser opcionalmente encriptada para asegurar su confidencialidad.

El encabezado de la ID Token, codifica la firma y los datos JSON en un string URL-safe base 64, para el fácil paso de datos, por ejemplo como parámetro URL.

Encabezado ID Token, como string URL

Cómo solicitar una ID Token

Una aplicación cliente, a la que se llama Relying Party(RP), puede solicitar una ID Token siguiendo una serie de pasos. Primero La autentificación del usuario debe ocurrir en un contexto confiable separado del contexto de la aplicación cliente, usualmente el navegador web. La sesión o credenciales del usuario serán verificadas por el navegador web, mediante popups redireccionadores en computadores, o lanzar el navegador del sistema en el caso de móviles. Vistas embebidas usualmente no se usan, para prevenir que el password se vea comprometido. OpenID Connect no especifica cómo se deben autentificar los usuarios, esto se deja a criterio de los proveedores, pero algunos de los métodos usados son: Nombre de Usuario y contraseña, Tokens de Hardware, Confirmación SMS, Biometría, etc. Luego las ID tokens son solicitadas mediante el protocolo OAuth 2.0, el cuál posee flujos para todos los tipos de aplicaciones: aplicaciones web tradicionales basadas en servidores, aplicaciones sólo para navegadores(Javascript), y aplicaciones nativas o de móviles. Estos flujos son:

  1. Authorization code:: El fujo más usado que funciona para aplicaciones web tradicionales y aplicaciones nativas/móviles. Involucra una redirección del navegador hacia/desde el OP para que el usuario sea autentificado y dé su consentimiento, luego una segunda solicitud de back-channel para recuperar la ID Token. En este flujo las tokens no se revelan en el navegador y la aplicación cliente también puede ser autentificada.
  2. Flujo Implícito: Para aplicaciones basadas en el navegador(Javascript) que no tienen backend. La ID Token se recibe directamente con la respuesta de redirección del OP. No se hace una solicitud de back channel.
  3. Flujo Híbrido: Raramente usado, permite al frontend y backend de la aplicación recibir tokens por separado. Esencialmente una combinación de los otros dos flujos.

He aquí una tabla comparativa de todos los flujos:

Tabla comparativa flujos

Usos de una ID Token

Las ID Tokens no sólo se pueden usar para registrar usuarios en aplicaciones.

  1. Sesiones sin estado: Usadas como una cookie de una navegador, la ID Token permite implementar sesiones ligeras sin estado. Esto elimina la necesidad de almacenar sesiones en el lado del servidor(en memoria o en disco), lo cual puede ser toda una carga para aplicaciones que requieran de escalabilidad. La cookie de sesión es chequeada al validar la ID Token. Si la token ha expirado, la aplicación simplemente puede pedirle una nueva al OP, mediante una solicitud silenciosa prompt=none.
  2. Paso de identidad a terceros: La ID Token puede se pasada a otros componentes de la aplicación o a servicios backend cuando se requiera conocer la identidad del usuario, por ejemplo para registrar el rastro de auditorías.
  3. Intercambio de tokens: La ID Token puede ser intercambiada por una access token en el token endpoint de un servidor de autorización OAuth 2.0(draft-ietf-oauth-token-exchange-03). Hay muchos escenarios donde se requiere un documento de identidad para obtener acceso a un lugar, por ejemplo al registrarse en un hotel para obtener la llave de la habitación. El intercambio de tokens tiene potenciales usos en aplicaciones empresariales.

Ejemplo de una autentificación OpenID

Ahora se hará un ejemplo de como obtener de un OP una ID Token para un usuario mediante el flujo Authorization Code. Esto consiste de dos pasos:

  1. Paso 1: Mediante un redireccionamiento frontend del navegador hacia un Authorisation Endpoint, se busca autentificar al Usuario y recibir su consentimiento. Resulta en un authorisation code que se usa como input en el paso 2.
  2. Paso 2: Mediante una solicitud backend de la aplicación cliente al servidor de autentificación, se busca autentificar al cliente y intercambiar el código para las tokens. Resulta en la obtención de una access token de OAuth 2.0(ID Token)
Código para el Paso 1

El RP inicia la autentificación del usuario al redirigir el navegador a un authorisation endpoint de OAuth 2.0 del proveedor de OpenID. La solicitud de autentificación es esencialmente una authorisation request OAuth 2.0 para acceder a la identidad del usuario. indicado por una valor openid en el parámetro scope. Código de ejemplo:

Consulta redirección de autentificación

Los parámetros que están dentro de la consulta URI:

  1. response_type: Indica que se usa el flujo Authorisation Code.
  2. scope: Especifica el ámbito de la autorización pedida. El scope value openid representa una solicitud para una autentificación OpenId y una Id Token.
  3. client_id: El identificador de la aplicación cliente(RP) al OP. Este identificador se obtiene típicamente cuando el RP se registra con el OP, por medio de la API de registro, consola de desarrollador, o algún otro método.
  4. state: Valor seteado por el RP para mantener el estado entre request y callback.
  5. redirect_uri: La dirección URL para redireccionar al usuario y que ingrese sus datos de autentificación.

Cuando es redireccionado hacia el OP, el usuario usualmente será autentificado chequeando si tiene una sesión válida(establecida por una cookie de navegador), y en la ausencia de eso se le solicitará haga login. Después se le preguntará si está de acuerdo en registrarse con el RP.

Pantalla de login y consentimiento del usuario hacia la aplicación cliente

El OP luego redirigirá al redirect_uri con un código de autorización (al tener éxito) o un código de error(si se denegó el acceso, o sí ocurrió algún otro error).

Respuesta código de autorización

The RP debe validar el parámetro state, y usar el código para proceder al siguiente paso., intercambiar el código por la ID Token.

Código para el Paso 2

El authorisation code es una credencial intermedia, que codifica la autorización obtenida en el paso 1. Sólo tiene sentido para el servidor OP, y ningún significado para el RP. Para recuperar la ID Token el RP debe entregar el código al OP, pero esta vez una solicitud backend es necesaria por dos razones:

  1. Para autentificar clientes confidenciales con el OP antes de revelar las tokens.
  2. Para entregar tokens directo al RP, evitando exponerlos en el navegador.

El código para el intercambio de tokens ocurre en el token endpoint del OP:

Código para intercambio de tokens

Los parámetros de la solicitud de tokens son:

  1. Authorization: El header indica el client_id y client_secret.
  2. grant_type: Indica que el flujo es authorization code.
  3. code: El authorisation code obtenido del paso 1.
  4. redirect_uri: Se repite la URL de redireccionamiento del paso 1.

Tras tener éxito el OP retornará un objeto JSON con la ID Token, una access token y una refresh token opcional:

Código respuesta con ID Tokens

La ID token es un JWT y debe ser cuidadosamente validada por el RP antes de ser aceptada. Notar que un bearer access token(que son una llave para acceder a un recurso protegido, por esta razón siempre deben pasarse por una canal asegurado TLS/HTTP) también esta incluido en la respuesta, para que cumpla con el protocolo Oauth 2.0. La access token es de utilidad cuando se solicita acceso a los datos del perfil de usuario en el UserInfo endpoint.

Atributos de Usuario(Claims)

En OpenID Connect existen una serie de métodos estandarizados para que las aplicaciones clientes puedan solicitar acceso a datos de usuarios(claims). Estas claims están pensadas para que la aplicación cliente tenga acceso a datos cuyo conocimiento fue consentido por el usuario, tales como email, nombre y fotos, tras hacer la solicitud. A continuación una tabla que lista estos métodos:

Datos de usuario y Claims asociadas

Las aplicaciones cliente pueden solicitar claims en 2 formas:

  1. Una categoría entera de claims por el valor de su scope, como se aprecia en la tabla.
  2. Individualmente, con el parámetro opcional para claims en las consultas.

Ahora un ejemplo de una solicitud para acceder a la identidad del usuario(ID Token) y su email, simplemente seteando el scope a openid email:

Claims openid email en consulta

Un importante criterio a tener en cuenta durante el diseño de las aplicaciones cliente, es que incluso si un usuario le da acceso a su identidad a una aplicación cliente, aún así pueden negar acceso a ciertas claims.

A continuación una claim en formato JSON:

Claim en formato JSON

Los OP pueden extender estas claims JSON estandarizadas para incluir atributos adicionales. Los nombres de estas claims adicionales deberían estar precedidas por una URL para evitar colisión de nombres.

Endpoints de OpenID Connect

Esta tabla resume los endpoints de un servidor de OpenID Connect:

Endpoints
Authorisation endpoint

Este es el endpoint del servidor OP donde al usuario se le pide autentificar y darle al acceso a la aplicación cliente a su identidad(ID Token) y potencialmente otros detalles requeridos, tales como email y nombre(claims). Este es el único endpoint donde el usuario necesita interactuar con el OP, usualmente a través del navegador web.

Token endpoint

El token endpoint autentifica a la aplicación cliente, luego les permite intercambiar el código recibido del authorisation endpoint por un ID token y una access token. El token endpoint también puede aceptar otros tipos de autorización OAuth 2.0 para otorgar tokens, tales cómo JWT assertion y SAML 2.0 assertion

UserInfo endpoint

El UserInfo endpoint retorna información del perfil del usuario, cuyo uso haya sido previamente consentido, a la aplicación cliente. Para esto se requiere una access token válida.

Consulta UserInfo

La UserInfo está en formato JSON y opcionalmente se puede empacar como una JWT que este firmada o encriptada.

UserInfo en formato JSON
Endpoint opcionales

A continuación se listan los endpoints opcionales de OpenId Connect:

  1. WebFinger: Permite el descubrimiento dinámico del proveedor de OpenID Connect(OP) para un usuario determinado, basado en su dirección email o alguna otra información.
  2. Provider metadata: Es un documento JSON que lista las URLs endpoint del OP y las características del servidor OpenID Connect / OAuth 2.0 que soporta. Las aplicaciones cliente pueden usar esta información para configurar sus consultas al OP.
  3. Provider JWK set: Es un documento JSON que contiene las llaves públicas del OP(usualmente RSA) en formato JSON Web Key (JWK). Estas llaves son usadas para asegurar las ID tokens otorgadas y otros artefactos.
  4. Client registration: Es una RESTful web API para registrar aplicaciones clientes con el OP. El registro puede ser protegido(requiere de preautorización) o puede ser público.
  5. Session management: Permite a las aplicaciones clientes el chequear si un usuario logueado aún tiene una sesión activa con el proveedor de OpenID Connect(OP). También para facilitar el hacer logout.

Bibliografía

  1. http://openid.net/connect/
  2. http://openid.net/specs/openid-connect-core-1_0.html
  3. https://developers.google.com/identity/protocols/OpenIDConnect

Comparativa entre NW.js y Electron

En la presente sección haremos una breve introducción a NW.js y a Electron, para finalmente presentar una comparativa entre ambos.

NW.js

NwjsLogo.png

Para entender su funcionamiento primero debemos entender que es Node.js. Node.js es un entorno en tiempo de ejecución multiplataforma, de código abierto, para la capa del servidor (pero no limitándose a ello) basado en el lenguaje de programación ECMAScript, asíncrono, con I/O de datos en una arquitectura orientada a eventos y basado en el motor V8 de Google. Fue creado con el enfoque de ser útil en la creación de programas de red altamente escalables, como por ejemplo, servidores web.

NW.js nació de la combinación entre Node.js y Chromium, de esta forma se encontró la manera de crear aplicaciones que no solo podían cargar sitios web locales sin ventanas de aplicación, sino que también podían interactuar con el sistema operativo gracias a JavaScript API, esta API no solo puede controlar aspectos visuales como lo son el tamaño de las ventanas toolbars y elementos de un menú, sino que también puede acceder a archivos locales del escritorio. Las principales acciones que se pueden hacer con NW.js son:


- Interactuar con el Sistema Operativo - Controlar el tamaño y comportamiento de las ventanas de aplicación - Mostrar toolbars nativos en la ventana de aplicación, con elementos de menú - Agregar context menus en la ventana de aplicación con el botón derecho - Agregar una bandeja de aplicación en la bandeja de menú del sistema operativo - Tener acceso al portapapeles del sistema operativo, leer el contenido o incluso configurar el contenido - Abrir archivos, carpetas y URL en el computador usando aplicaciones default - Insertar notificaciones a través del sistema de notificaciones del sistema operativo.


Intel XDK: Aplicación para el desarrollo e implementación de aplicaciones HTML5 de manera rápida y simple. Scoop: Scoop es una aplicación organizadora de fotos disponible en la Mac App Store, permite compartir de manera más sencilla fotos con tu familia y amigos. Lolconf: Tablero de configuraciones del juego League of Legends

Electron

Electron 0.36.4 Icon.png

Electron es un framework desarrollado por GitHub que permite el desarrollo de aplicaciones de escritorio mediante el uso de una combinación de Chromium, Node.js (o alternativamente JavaSctipt I/O) y V8. Nació como base sobre la que se desarrolló Atom, un editor de código creado por GitHub. Originalmente se llamaba Atom Shell, pero con el tiempo mucha gente lo comenzó a utilizar para desarrollar otras aplicaciones por lo que en GitHub decidieron convertirlo en un proyecto independiente. El nombre se cambió a Electron para enfatizar el hecho de que ya no tenía relación directa con Atom.

Muchas aplicaciones de escritorio de todo tipo utilizan Electron, incluyendo editores de texto, reproductores de música, videojuegos, etc., lo que demuestra la flexibilidad de este esquema. Algunos ejemplos son los siguientes:

La estructura básica de una aplicación en Electron contiene tres archivos: package.json, main.js y index.html. Package.json contiene la metadata de la aplicación, main.js contiene el código y index.html contiene la interfaz de usuario. A partir de esto se puede ir expandiendo la aplicación.

Electron tree.png

Hay que tener presente un par de cosas cuando se desarrolla en Electron. Lo primero es que Electron utiliza sólo las librerías de renderizado de Chromium, por lo que no se tendrá acceso a todas las funciones de dicho programa. Lo segundo es que Electron no sigue semver, esto por las relaciones de dependencia que tiene con Node.js y Chromium. En lugar de eso utiliza una versión modificada donde se siguen las siguientes reglas:

  • Pasar de una versión mayor a otra impedirá el funcionamiento de la aplicación, por lo que la aplicación también debe ser actualizada por el desarrollador para utilizar la nueva versión de Electron.
  • Pasar de una versión menor a otra es probable que cause problemas menores en la aplicación, pero no debiera impedir su funcionamiento. Por esto para pasar de una versión menor a otra el desarrollador deberá verificar que todo funciona correctamente y corregir donde haga falta.
  • Pasar de una versión parche a otra no debiera tener ningún efecto en la aplicación por lo que no debiera requerir de ningún cambio en la aplicación por parte del desarrollador.

NW.js vs Electron

Electron provee una funcionalidad muy similar a NW.js, pues ambos tienen el mismo propósito general.

Tabla parte 1.png Tabla parte 2.png Tabla parte 3.png


Tal cual está mencionado anteriormente, NW.js utiliza Chromium, mientras que Electron utiliza la librería libchromiumcontent para acceder al contenido de la API de Chromium, esto está catalogado como una ventaja para NW.js pero no es inherentemente superior.

En el caso de Electron respecto a usar libchromiumcontent, ésta es una librería compartida que incluye el contenido del módulo de Chromium y todas sus dependencias por lo que se requiere de menos recursos por parte del computador del desarrollador. Otro aspecto es el soporte, en el caso de Windows XP y Mac OS X.6 (versiones antiguas que muchos usuarios prefieren) el cual Electron no provee, limitando su impacto expansivo multiplataforma, aunque eso podría cambiar en el futuro, y también está el hecho de que Electron requiere de instalar paquetes adicionales para poder soportar completamente el Windows App Store, ver archivos PDF y utilizar certificados de cliente SSL.

Por último está la comunidad, Electron fue lanzado 2 años después que NW.js, pero el tiempo promedio que tarda la comunidad en resolver problemas en sitios como GitHub o stackoverflow es bastante menor, así como la cantidad de problemas que aún están por resolver. A esto se añade que en GitHub, Electron tiene mayores números en watches, stars y forks, aunque esto puede deberse a que el sponsor corporativo de Electron es GitHub, creando un sesgo relativo, pero aún así denota mayor motivación por parte de la comunidad.

Saliendo de la tabla es necesario también mencionar que los paradigmas en los cuales se enfocan NW.js y Electron son distintos:

En el caso de NW.js es mas orientado al browser, básicamente carga la págnia HTML y esa página es la que obtiene acceso al contexto del nodo.js, si mas de una ventana está abierta, entonces todas ellas tienen acceso al contexto (ahora compartido) del nodo.js, esto implica que puede ser directamente accesado desde el DOM (Document Object Module) de todas las ventanas abiertas transparentemente.

Electron, por el otro lado tiene un enfoque orientado al nodo.js, ya que se inicializa un node.js runtime el cual tiene la capacidad de abrir ventanas en las cuales se cargan las páginas web, éste punto de vista implica que el equipo de desarrollo de NW.js tiene que trabajar mas con el código de base de Chromium, para que pueda hacerle el plug in al ambiente de nodo.js, pero se gana en que los ambientes del nodo.js y el navegador interactúan de manera mas fluída.

A modo de conclusiones, no hay un claro ganador, ambos son excelentes frameworks para desarrollar, es un gran “depende”, mayoritariamente del contexto del usuario y de lo que él quiera crear, por ejemplo: Para el caso de los estudiantes de la USM, el tema de Chromium vs libchromiumcontent no importa, ya que los computadores que provee la universidad son lo suficientemente poderosos para lidiar con Chromium en su totalidad, así como el tema de la portabilidad a Windows XP o Mac OS X.6, ya que Linux está integrado en todos los computadores de nuestros laboratorios, y ambos frameworks funcionan en ese entorno, pero como estudiantes la información en muy importante por lo que la comunidad es clave, en ese aspecto, aún puede haber dudas, ya que NW.js ha estado por mayor tiempo, por lo que hay mayor contenido para informarse, pero respecto a la resolución de problemas (ya que tendremos muchas dudas y nos encontraremos con varios errores al programar) Electron tiene una clara ventaja.

Incluso, si el proyecto es lo suficientemente pequeño, Python o QT son excelentes herramientas, no es necesario meterse de lleno en Electron o NW.js y gastar una buena cantidad de tiempo en revisar las documentaciones.

Herramientas personales
Espacios de nombres
Variantes
Acciones
Navegación
Herramientas