Nuevo blog: eiximenis.github.io

El mundo ha cambiado. Lo siento en el agua, lo siento en la tierra, lo huelo en el aire.

Sirvan esas palabras de Fangorn para decir que abro un nuevo blog, alojado en GitHub pages, que podeis encontrar en eiximenis.github.io. Llevaba ya bastante tiempo meditando un cambio y al final, después de hablar con Álex Casquete, me he decantado por usar Jekyll y hospedar el blog en GitHub pages.

¿Por qué el cambio?

Hace ya casi ocho años que abrí el blog en geeks.ms y la verdad es que muchas cosas han cambiado en este tiempo. Por un lado, la propia plataforma de geeks se queda un poco corta, en especial los templates para móvil son bastante malos. Hace años era un mal menor, ahora es importante, cada vez se consumen más y más blogs desde móviles. Es importante para mí que mi blog se vea bien en dispositivos móviles, y eso con geeks era complicado. Y no hay que negar que al community server se le notan los años y algunas tareas eran complicadas o tediosas… y suerte de Live Writer, porque si no, ¡si que hubiese sido infernal!

No es tampoco la única razón: en todo esto tiempo he intentado mantener este blog centrado en .NET y el desarrollo web (las tecnologías que más uso en mi día a día). Pero desarrollo en muchas otras tecnologías, quizá no a nivel profesional, pero también me apetece contar cosas sobre esas otras tecnologías que poco o nada tienen que ver con .NET o con Microsoft. Tengo la sensación que este blog no es el lugar apropiado (aunque nunca nadie me ha dicho que puedo o no puedo publicar en geeks).

La verdad es que el cambio siempre me ha dado mucha pereza… pero ahora creo que es el momento.

¿Eso significa que este blog en geeks muere?

No, lo que se llama morir no. Cuando publique un post que tenga que ver con .NET en mi nuevo blog, publicaré aquí un resúmen con el enlace completo al blog nuevo. No haré crossposting al uso, primero porque no me gusta y segundo porque no sé como hacerlo desde Jekyll. Así que cuando publique algo que vea que tiene sentido que también esté aquí, publicaré aquí un pequeño resúmen y pondré el enlace al post completo en mi blog.

Pero al margen de eso no habrán nuevas actualizaciones en este blog.

¿Por qué Jekyll?

Realmente Jekyll no es un sistema de blogs tradicional, como puedan ser blogger, el community server que hospeda geeks o el más famoso wordpress. Jekyll es un generador de sitios estáticos: toma unas plantillas que tienen una sintaxis específica (parecida a mustache, que ellos llaman “Liquid templates”), procesa todas esas plantillas y genera ficheros .html planos. Luego esos ficheros puedes servirlos con cualquier servidor web estático.

La idea es muy simple y es una maravilla.

Primero porque los posts pasan a ser código. En el caso de jekyll los posts se suelen codificar en markdown (aunque puedes usar directamente html) y luego mediante una plantilla se convierte a html y se le pone el layout. Jekyll genera resúmenes, paginadores, tags ¡e incluso un feed! Pero no hay base de datos alguna, no hay un sistema CMS por debajo, ni nada parecido.

A pesar de no haber base de datos, es posible dar soporte a comentarios gracias a Disqus, o sea que el tema de los comentarios también está solucionado 😉

Y luego está la integración con GitHub Pages. Jekyll es el motor que hay debajo de GitHub Pages, por lo que eso significa que si hospedas tu blog allí, no subes los contenidos estáticos que te genera Jekyll, si no que subes las plantillas y GitHub las ejecuta y actualiza tu GitHub pages con el resultado de ejecutar Jekyll. Eso tiene la ventaja de que tu blog pasa a ser un repositorio de GitHub: si tienes que editar un post, simplemente editas el markdown asociado, haces push y automáticamente GitHub hace el resto. El inconveniente es que debes ceñirte al entorno que tengan en GitHub pages: hay ciertos plugins de Jekyll que no puedes usar y cosas similares. Nada es perfecto :)

¿Qué habrá en el nuevo blog?
Pues básicamente lo mismo que en este, pero hablando de más cosas, no solo de .NET. Pero va a haber lo mismo: artículos técnicos, algún artículo de opinión de vez en cuando y todo aquello que me apetezca hablar.

¡O sea que nada más! Si me has estado siguiendo todo este tiempo en geeks.ms, ya sabes donde encontrarme ahora.

¡Nos seguimos leyendo!

Como depurar fácilmente el código de ASP.NET5

¡Muy buenas! Para los que andamos trasteando con versiones alfas y betas con nula o poca documentación, poder depurar el código fuente de las librerías es una manera muy buena de ver qué hace y como lo hace. Cierto, solo leyendo el código fuente se puede aprender mucho, pero poder depurarlo paso a paso es todavía más útil.

El primer paso es, por supuesto, disponer del código fuente. En según que librerías eso no es posible, aunque siempre se podía tirar de los desensambladores (por más que eso pueda no ser legal). El problema de usar los desensambladores es que el código fuente obtenido no siempre es muy legible y que por otro lado no puedes depurarlo a no ser que tu desensemblador soporte la creación de PDBs.

Depurar ASP.NET MVC nunca ha sido un problema importante, en tanto el código fuente estaba disponible. Podías descargarte el código fuente de ASP.NET MVC, compilarlo en alguna carpeta local, pongamos c:mvc, junto con sus PDBs. Luego tenías que modificar tu proyecto web, quitar las referencias a ASP.NET MVC reales y sustituirlas por las versiones locales con PDBs. Con eso, podías depurar ASP.NET MVC sin muchos problemas. Pero era un poco peñazo el tener que sustituir las referencias reales por las tuyas compiladas, lo que podía redundar en algún cambio adicional de configuración (por estar firmadas las reales y no estarlos, o estarlo con otra clave, las locales).

En ASP.NET5 el proceso se ha vuelto ridículamente simple. El proceso es como sigue:

  1. Clona los repositorios de ASP.NET5 que quieras. P. ej. yo he clonado algunos de ellos en la carpeta c:tfsaspnet5.
  2. Crea un proyecto web con VS2015 que use ASP.NET5. O abre un proyecto existente, eso es lo de menos.
  3. Abre el fichero global.json que está en Solution Items

Este fichero contiene en “projects”, la lista de carpetas en las que VS2015 sabe que hay código que debe incorporar como parte de tu proyecto (por defecto las carpetas src y test). Añade la carpeta base en la cual has clonado los repos de aspnet5 que quieras depurar:

  1. {
  2.   "projects": [ "src", "test", "c:/tfs/aspnet5/mvc/src" ],
  3.   "sdk": {
  4.     "version": "1.0.0-beta8"
  5.   }
  6. }

En mi caso en c:tfsaspnet5mvc he clonado el repo de ASP.NET MVC6 así lo añado en projects (debo añadir el /src final que es donde hay los proyectos). Eso automáticamente me añade los proyectos de ASP.NET MVC6 a mi solución:

image

Además en el solution explorer VS2015 nos indica, con un icono distinto, qué referencias ha cargado en local:

image

Ahora puedes navegar por el código fuente y colocar breakpoints sin ningún problema… ejecutar tu aplicación y ¡depurar!

image

Eso sí, la clave para que te funcione es que tengas los repos sincronizados con la versión que estás usando. P. ej. si en el project.json estás referenciando la versión 1.0.0-beta8 debes tener los repos con el código fuente que se corresponda a dicha versión (todas las versiones tienen un tag de Git asociado, así que puedes obtener la que quieras). También que estés usando el entorno de ejecución correspondiente (no te funcionará si intentas depurar beta8 usando el dnx de beta5).

Observa que no es necesario cambio alguno en nuestro proyecto. Cuando hayas depurado, basta con que elimines del global.json el directorio con los fuentes y tu aplicación pasará a referenciar los paquetes NuGet oficiales.

Más fácil, ¡imposible!

Saludos!

PD: Antes de que me deis las gracias, se las dáis a Hugo Biarge (@hbiarge) que fue quien me lo contó. En este post hay más info (un poco desactualizada, ojo): http://blogs.msdn.com/b/webdev/archive/2015/02/06/debugging-asp-net-5-framework-code-using-visual-studio-2015.aspx

Variables privadas en clases ES2015

Una de las novedades de ES6 es la posibilidad de usar clases. Si bien esas clases son realmente sugar syntax sobre el patrón de función constructora, tienen alguna característica que simplifica el uso de dicho patrón y ofrecen una sintaxis que según como se mire puede ser más cómoda. Pero el estándard de ES2015 no tiene ningún mecanismo para indicar que una variable de una clase sea pública o privada. La visibilidad de variables en JavaScript es un clásico, sobre el que ya he escrito algún post. Pero las técnicas que usábamos hasta ahora para simular la visibilidad privada no aplican cuando usamos la sintaxis de clases… y debemos usar mecanismos alternativos. En este post veremos dos de ellos.

Supongamos que tenemos una clase ES2015 como la siguiente:

  1. class Foo {
  2.     constructor(name) {
  3.         this._name = name;
  4.     }
  5.  
  6.     get name() {
  7.         return _name;
  8.     }
  9. }

El objetivo es que _name sea privado y solo pueda accederse a su valor a través de la propiedad name.

Símbolos al rescate

La primera solución implica el uso de un nuevo concepto de ES2015: los símbolos. Un símbolo permite definir un nombre único desconocido y que tan solo puede ser obtenido a partir de la referencia al símbolo original que ha creado dicho nombre.  El siguiente código explica el uso de símbolos:

  1. var sfoo = Symbol("foo");
  2. var a = {};
  3. a[sfoo] = "sfoo";
  4. console.log(a.sfoo); // undefined
  5. console.log(a[sfoo]);   // sfoo
  6. console.log(a[Symbol("foo")])    // undefined

Podemos asignar una propiedad de un objeto a un símbolo, y entonces requerimos del símbolo para poder obtener el valor de la propiedad. Observa que necesitamos el símbolo original (almacenado en sfoo), crear otro símbolo a partir de la misma cadena, no sirve. Los símbolos son únicos.

Por lo tanto ahora podemos simular variables privadas de la siguiente manera:

  1. const s_name = Symbol("name");
  2. export default class Foo {
  3.     constructor(name) {
  4.         this[s_name] = name;
  5.     }
  6.     get name() {
  7.         return this[s_name];
  8.     }
  9. }

Los objetos de la clase Foo tienen una variable cuyo nombre es el símbolo guardado en s_name. Esa variable “no es realmente pública”, pero no hay manera de encontrar su nombre fuera del módulo que declara la clase (la variable s_name que contiene el símbolo, es privada del módulo por lo que no es accesible desde el exterior). Observa que no basta que alguien mire el código fuente del módulo y se cree otro Symbol(“name”) para acceder a la variable “privada”: los símbolos son únicos, o lo que es lo mismo: Symbol("a") != Symbol("a").

Este método no genera variables totalmente privadas. Las variables que están almacenadas en una propiedad cuyo nombre es un símbolo, no se listan en Object.getOwnPropertyNames y tampoco participan de la iteración de for..in pero se pueden obtener todos los símbolos asociados a un objeto mediante Object.getOwnPropertySymbols, que devuelve un array con todos los símbolos usados como nombre de propiedad del objeto. Basta con usar los símbolos devueltos para acceder a las variables “privadas”.

Por lo tanto este sistema, vendría a equivaler a la visibilidad private de C# para entendernos: Por defecto es imposible acceder a la propiedad, pero tenemos un mecanismo (en C# es Reflection) que nos permite saltarnos esa protección y acceder al contenido de la variable “privada”.

Weak maps

El uso de weak maps nos permite tener variables completamente privadas. Para ello usamos el nuevo tipo WeakMap de ES2015, que básicamente es un diccionario clave, valor, pero es especial porque no impide al GC de JavaScript recolectar todos aquellos valores almacenados en el weak map, siempre y cuando la referencia a la clave que tenga el weak map sea la única restante. Es decir, a todos los efectos el weak map no cuenta para el GC: aunque un objeto esté almacenado en él, si la clave usada no está referenciado por ningún otro objeto, el GC lo podrá eliminar.

El código usando WeakMap es el siguiente:

  1. const privates = new WeakMap();
  2. export default class Foo {
  3.     constructor(name) {
  4.         privates.set(this, {name: name});
  5.     }
  6.     get name() {
  7.         return privates.get(this).name;
  8.     }
  9. }

La idea es muy sencilla: por cada objeto que se cree de Foo, se almacena un valor en el WeakMap privates. La clave de dicho valor es this, que es el propio objeto Foo que se crea. Este objeto (privates.get(this)) almacena todo el estado “privado” del objeto Foo en cuestión. Gracias al hecho de que privates es un WeakMap no hay memory leak: Cuando el objeto Foo deje de usarse podrá ser eliminado por el garbage collector, aunque esté referenciado por el WeakMap como una de las claves usadas (precisamente por ser un privates Weak Map).

La clave (nunca mejor dicho :P) del asunto está en usar this como clave del Weak Map privates.

Al igual que en el caso del símbolo, el Weak Map es una variable privada del módulo, por lo que no se puede acceder a fuera desde él. Y a diferencia del caso del símbolo, ahora si que no hay nada que nadie pueda hacer para acceder a la variable privada que almacena el valor del nombre.

Saludos!

[Evento]–Hel10 Windows

Buenas! Ayer (22 octubre 2015) se celebró el “Hel10 Windows” un evento organizado por Microsoft en Madrid para hablar de las muchas novedades que incorpora Windows 10 y todo el ecosistema nuevo de la plataforma universal.

Antes que nada mi opinión general del evento: Estuvo basante bien. Una keynote un poco sosilla para mi gusto, a pesar de que algunas de las novedades presentadas eran bastante interesantes. Pero, por un lado vivimos en la época de la información globalizada y quien más quien menos ya había oído hablar de continuum y el resto de novedades, y por otro no tenemos el sentido del espectáculo de los americanos (por suerte o por desgracia según cada cual).

Después de la keynote empezaron cuatro tracks, los nombres oficiales de los cuales están el la página del evento, pero que básicamente eran:

  1. Desarrollo de aplicaciones universales y la UWP. Este track es el que se ha retransmitido via channel 9.
  2. Cosas raras de desarrollo. En este track estuve yo hablando sobre WinObjC.
  3. IoT y cacharritos
  4. Sistemas

Como digo yo estuve hablando de WinObjC o lo que es lo mismo “project Islandwood” o “Bridge for iOS” que es el nombre oficial. Se trata de un conjunto de herramientas que permitirá portar nuestras aplicaciones iOS en Objective-C a Windows10 como aplicación universal. Manteniendo la funcionalidad pero adaptando un poco el aspecto al aspecto de las aplicaciones universales.

Durante la charla tuve malditos problemas técnicos con Parallels que básicamente me impidió ejecutar las demos. Mucha rabia porque había usado Parallels (de hecho lo uso constantemente) sin problemas, pero no se si fue que el proyector estaba en una resolución no soportada por mi Mac o qué, pero el resultado es que el ratón en Parallels iba donde le daba la gana y era imposible darle click a nada… En fin, que le vamos a hacer. Me limité a mostrar el código en XCode y como usar compilación condicional para reemplazar aquellas partes que el bridge no soporta con llamadas a la API nativa de Windows 10.

En la charla intenté explicar un poco lo que hay hecho, pero sin engañar a nadie: el proyecto está muy verde, y es más la promesa de lo que va a ser que lo que es en la actualidad. El soporte para ficheros.xib, storyboards y layout constraints es casi obligatorio, porque sin esas tres características casi no se va a poder migrar aplicación alguna (excepto juegos). Lo que hay hecho, a pesar de ser una preview que, en mi opinión, no llega ni a alfa, pinta interesante, pero se tiene que ver como evoluciona.

He dejado la presentación de la charla en slideshare: http://www.slideshare.net/eduardtomas/winobjc-windows-bridge-for-ios

Y si te animas a probar las demos, las he subido todas a un repo de github para que puedas jugar con ellas: https://github.com/eiximenis/WinObjC-Samples

Saludos!

¿Qué hace ‘new’ en JavaScript?

Si preguntas a mucha gente cual es el objetivo de new en JavaScript te dirán que el de crear objetos. Y estarán en lo cierto, aunque esa definición no es del todo precisa. Y es que mucha gente no entiende exactamente que hace new así que vamos a dedicarle este post.

Creación de objetos sin new

La verdad es que new no es necesario en JavaScript. Se pueden crear objetos perfectamente sin necesidad de usar new:

  1. var foo = {
  2.     name: 'foo',
  3.     getUpperName: function () {
  4.         return this.name.toUpperCase();
  5.     }
  6. }

Esta manera de crear objetos la conocemos como object notation y nos permite definir objetos con campos y métodos. Por supuesto, en este caso solo creamos un objeto pero basta con declarar una función que tenga ese código para crear tantos objetos como queramos:

  1. var Foo = function (name) {
  2.     var foo = {
  3.         name: name || '',
  4.         getUpperName: function () {
  5.             return this.name.toUpperCase();
  6.         }
  7.     }
  8.  
  9.     return foo;
  10. }
  11.  
  12. var f2 = Foo("f2");
  13. f2.getUpperName();  // devuelve F2

Nos podemos preguntar cual es el prototipo de cada objeto creado mediante una llamada a Foo. Pues, como es de esperar, el prototipo de f2 será Object.prototype.

Podríamos indicar que los objetos creados por Foo heredan de Foo.prototype, con un código similar al:

  1. var Foo = function (name) {
  2.     var foo = {
  3.         name: name || '',
  4.         getUpperName: function () {
  5.             return this.name.toUpperCase();
  6.         }
  7.     }
  8.     Object.setPrototypeOf(foo, Foo.prototype);
  9.     return foo;
  10. }
  11.  
  12. var f2 = Foo("f2");
  13. f2.getUpperName();  // devuelve F2
  14. f2 instanceof Foo; // devuelve true

Lo interesante es que establecer como prototipo del objeto creado el objeto Foo.prototype, automáticamente hace que instanceof Foo devuelva true sobre todos los objetos creados por la función Foo. Vale, estoy usando Object.setPrototypeOf que es una función nueva de ES2015, pero en ES5 clásico tenemos Object.create que nos permite hacer lo mismo:

  1. var Foo = function (name) {
  2.     var foo = Object.create(Foo.prototype);
  3.     foo.name = name || '';
  4.     foo.getUpperName = function () {
  5.         return this.name.toUpperCase();
  6.     }
  7.     return foo;
  8. }
  9.  
  10. var f2 = Foo("f2");
  11. f2.getUpperName();  // devuelve F2
  12. f2 instanceof Foo; // devuelve true

¿Entonces… qué hace new?

Bueno, new se introdujo para dar una “sintaxis familiar” a los desarrolladores que venían de Java, pero básicamente hace lo mismo que hemos hecho nosotros. En JavaScript hablamos de funciones constructoras, pero no hay sintaxis para declarar una función constructora. Una función constructora es aquella pensada para ser llamada con new, pero que quede claro: es usar o no new al invocar una función lo que convierte a esa en constructora.

Cuando usamos new en una función, llamémosla Bar, ocurre lo siguiente:

  1. Se crea automáticamente un objeto vacío que hereda de Bar.prototype
  2. Se llama a la función Bar, con el valor de this enlazado al objeto creado en el punto anterior
  3. Si (y solo sí) la función Bar devuelve undefined, new devuelve el valor de this dentro de Bar (es decir, el objeto creado en el punto 1).

Como, gracias al punto 2, dentro de una función llamada con new el valor de this es el objeto creado en el punto 1, decimos que en una función constructora el valor de this es “el objeto que se está creando”. Y es por ello que las codificamos de esa manera:

  1. var Foo = function (name) {    
  2.     this.name = name || '';
  3.     this.getUpperName = function () {
  4.         return this.name.toUpperCase();
  5.     }
  6. }

Pero para que veas exactamente hasta que punto new no era “imprescindible” es porque incluso podríamos hacer una especie de polyfill para new:

  1. var functionToCtor = function (ctor) {
  2.     var o = Object.create(ctor.prototype);
  3.     var args = Array.prototype.slice.call(arguments)
  4.     args.splice(0, 1);
  5.     var v = ctor.apply(o, args);
  6.     return v === undefined ? o : v;
  7. }

La función functionToCtor hace lo mismo que new. Es decir, en este caso dada la función constructora Foo ambas expresiones son equivalentes:

  1. var foo = functionToCtor(Foo, "foo");
  2. var foo2 = new Foo("foo2");

Tanto foo como foo2:

  • Tienen como prototipo Foo.prototype
  • Tienen como constructor la función Foo
  • Devuelven true a la expresión instanceof Foo

¿Y si una función constructora devuelve un valor?

Esa es buena… Pues en este caso cuando se use new el valor obtenido será el devuelto por la función constructora (siempre que este valor sea distinto de undefined):

  1. var Foo = function (name) {    
  2.     this.name = name || '';
  3.     this.getUpperName = function () {
  4.         return this.name.toUpperCase();
  5.     }
  6.  
  7.     return { a: 10 };
  8. }
  9.  
  10. var f = new Foo();
  11. f.a;        //  10
  12. f instanceof Foo // false

Si… a pesar de que f ha sido creado usando new Foo, el prototipo de f ya no es Foo.prototype, ya que f vale el objeto devuelto por la función Foo. En este caso el objeto “original” cuyo prototipo es Foo.prototype y al que nos referíamos con this dentro de Foo se ha perdido. Lo mismo ocurre si usas el “polyfill” functionToCtor que hemos visto antes.

Funciones duales

Podemos hacer una función que sepa si se ha invocado con new o no? Pues sí:

  1. var Foo = function (name) {
  2.     if (this instanceof Foo) {
  3.         // Invocada con new
  4.     }
  5.     else {
  6.         // Invocada sin new
  7.     }
  8. }

Esto nos permite trabajar con this en el caso de que se haya usado new o bien no trabajar con this y devolver un valor en el caso de que no se haya invocado a la función con this. De todos modos si quieres que el usuario obtenga el mismo valor use new o no, lo más fácil es devolver el valor desde la función constructora. En este caso, eso sí, pierdes el hecho de que el prototipo del objeto sea la función constructora. Si quieres asegurarte que el usuario obtiene siempre un objeto con el prototipo asociado a la función constructora, es decir como si siempre usase new, puedes hacer:

  1. var Foo = function (name) {
  2.     var _create = function (name) {
  3.         this.name = name || '';
  4.         this.getUpperName = function () {
  5.             return this.name.toLocaleUpperCase();
  6.         }
  7.     }
  8.  
  9.     if (this instanceof Foo) {
  10.         _create.bind(this)(name);
  11.     }
  12.     else {
  13.         var o = Object.create(Foo.prototype);
  14.         _create.bind(o)(name);
  15.         return o;
  16.     }
  17. }

La función _create es la que realmente rellena el objeto (le llega ya creado en la variable this). La función Foo lo único que hace es mirar si ha sido llamada con new o no. En el primer caso llama a _create pero vinculando el valor de this dentro de _create al propio valor de this dentro de Foo (que en este caso es el objeto que se está creando) y no devolver nada. En el caso que el usuario no haya usado new la función Foo crea un objeto vacío, le asigna Foo.prototype como prototipo y luego llama a _create vinculando el valor de this dentro de _create al del objeto que acaba de crear. Y finalmente, en este caso, devuelve el objeto creado.

Así, tanto si el usuario hace var x = Foo() como var x2 = new Foo() obtiene lo mismo: un objeto cuyo prototipo es Foo.prototype y que por lo tanto devuelve true a instanceof Foo.

Espero que este post os haya ayudado a entender como funciona new en JavaScript.

Saludos!

Algunas consideraciones de seguridad sobre OAuth

Cuando hablo de OAuth y del acceso con tokens, ya sea en formaciones o en charlas más o menos coloquiales, muchas veces surgen dudas sobre cuan seguros son los tokens. En este post, sin pretender dar un repaso exhaustivo a todos los flujos OAuth existentes, si que me gustaría comentar algunas consideraciones básicas de seguridad.

En el principio estaba OAuth 1.0

La versión 1.0 de OAuth especifica, básicamente, un solo token, conocido como oauth_token. Dicho token es el que, enviado junto a una petición, permite validar que la petición es enviada un cliente en concreto. Dejando de lado como obtenemos dicho token (los distintos flujos OAuth) el resultado final es que el cliente debe mandar lo siguiente en cada petición:

  1. El oauth_consumer_key: El ID (público) de cliente. Dicho ID identifica a la aplicación cliente, aunque no a un usuario determinado. Es decir, identifica a la aplicación cliente, no al usuario.
  2. El oauth_token que identifica a un usuario en concreto. El oauth_token conjuntamente al oauth_consumer_key identifican un usuario concreto de una aplicación.

Visto así, parece que si alguien interceptase una petición concreta, podría ver tanto el oauth_consumer_key como el oauth_token y de esa manera impersonar al usuario en concreto. Para protegernos de eso, lo más sencillo es usar un canal seguro (es decir https) pero OAuth 1.0 incorpora un mecanismo para securizar nuestros tokens incluso en canales no seguros: la firma de peticiones.

Cada petición OAuth debe ir firmada digitalmente, y esa firma digital se realiza utilizando otro token (oauth_token_secret), dicho token es conocido es conocido solo por el cliente y el servidor y no es enviado nunca por el cliente (el cliente lo recibe junto su token oauth cuando realiza el flujo correspondiente). De esta manera si alguien intercepta una petición y obtiene tanto el oauth_consumer_key como el oauth_token no podrá generar nuevas peticiones válidas, ya que no podrá firmarlas. Por supuesto podría reenviar la petición tantas veces como quisiera (lo que podría tener consecuencias fatales), pero nunca podría enviar una petición modificada o con otros datos.

Para evitar que alguien pueda reenviar una petición se establece un nuevo mecanismo de seguridad en OAuth: Cada petición incluye un nonce (acrónimo de “number once”) que es un identificador “único” de petición. El formato del nonce queda a elección del servidor (puede ser un guid, puede ser un timestamp en formato Unix, o cualquier otra cosa). La idea es que el servidor no aceptará dos peticiones del mismo cliente con el mismo nonce (en cierto intervalo de tiempo a definir por el servidor). Además, las peticiones OAuth llevan un timestamp que indica cuando el cliente las emite (en un tiempo que debe estar sincronizado con el del servidor, por lo que se suele usar UTC). El servidor valida dicho timestamp y si no coincide con el de la hora del servidor (dentro de cierto margen de tolerancia) la petición es rechazada. De este modo basta con que los nonce no se puedan repetir en todo el periodo de tolerancia del timestamp. Debe notarse que tanto el nonce como el timestamp forman parte de la petición, por lo que son firmados digitalmente (y por lo tanto no pueden alterarse).

Creedme si os digo por experiencia que la parte más dura de crear un cliente (o un servidor) OAuth es la creación y/o validación de las firmas digitales. Eso incluye crear lo que la especificación llama una “forma canónica de la petición” que no es trivial. La gran mayoría de errores de implementación de clientes o servidores OAuth vienen por ahí.

A cambio tenemos una cierta garantía de que incluso en canales no seguros, si alguien intercepta una petición no podrá usar los tokens para generar nuevas peticiones y impersonar al usuario. Las únicas peticiones en OAuth 1 que debemos mandar bajo https sí o sí son las que nos permiten obtener los tokens iniciales… Aunque mi recomendación sería usar siempre https por supuesto.

OAuth 2 y los bearer tokens

OAuth 2 cambió las normas del juego: dado que la generación y validación de la firma digital son complejos, en OAuth 2 se elimina la firma digital, lo que deja los tokens en una situación bastante más comprometida.

De hecho si en OAuth 1 era bastante natural que un oauth_token tuviese una validez muy larga (o incluso que no caducase) en OAuth 2 eso sería como pegarse un tiro: Una vez el cliente obtiene un token oauth (al igual que en OAuth 1.0 existen varios flujos para hacerlo) dicho token realmente impersona al usuario. Es decir, si alguien intercepta el token, es a todas luces, como si tuviese las credenciales del usuario… durante el tiempo de validez del token. A ese tipo de tokens los conocemos como bearer tokens.

Insisto para dejarlo claro: si una petición incluye el bearer token dicha petición se considerada autenticada y además impersona a un usuario en concreto. Por lo tanto cualquiera que intercepte una petición que incluya el bearer token tiene abiertas las puertas de par en par.

Para minimizar daños se hace que los bearer tokens tengan una duración corta (lo de corta depende de cada uno), de forma que a pesar de tener un bearer token uno puede, al cabo de cierto tiempo, recibir un 401 lo que indica que el token ha caducado. En este caso existe un flujo OAuth 2 que permite “renovar” el token. Renovar el token incluye enviar otro token específico (el refresh token). Dicho token se obtiene junto al token de acceso y sirve solo para esto: para refrescar el token de acceso cuando ha caducado. Dado que el refresh token no viaja en cada petición, alguien que haya obtenido un token oauth, no podrá renovarlo.

Por supuesto si este alguien que está escuchando intercepta una petición de “refresco de token” entonces si que la situación se vuelve complicada de verdad: a pesar de que los refresh tokens pueden caducar la verdad es que su tiempo de vida suele ser muy largo y aunque se pueden revocar esto solo consigue “cerrar las puertas” una vez alguien ya ha podido hacer daño.

En resumen OAuth 2 con los bearer tokens toma una filosofía muy clara: que el canal de comunicaciones es seguro. O dicho de otro modo: no puede usarse OAuth 2 con bearer tokens si no se usa un canal seguro (https). Y no me refiero solo a las peticiones que obtienen los tokens, si no a todas. Todas las peticiones OAuth 2 con bearer tokens deben enviarse bajo https. Si no, la seguridad queda totalmente comprometida.

MAC Tokens

Para ser justos con OAuth 2, no obliga a usar bearer tokens (a pesar de que esos sean los más usados). OAuth 2 soporta también otro tipo de tokens, conocidos como tokens MAC (Message Authentication Code). En este caso OAuth 2 se comporta de forma parecida a OAuth 1: cuando el cliente obtiene el token, obtiene también otro token adicional que le sirve para firmar las peticiones. En este caso, al igual que en OAuth 1, se usan los parámetros nonce y timestamp de la petición para evitar que alguien pudiese reenviar peticiones. Al igual que en OAuth 1 se soportan varios algoritmos de firma digital (aunque HMAC SHA256 suele ser el más usado).

Si usamos tokens MAC el requisito de canal seguro desaparece, excepto, por supuesto, en las peticiones que permiten obtener los tokens.

Os dejo algunos enlaces con más información al respecto:

Espero que si teníais alguna duda al respecto esto os ayude un poco :)

La dualidad objeto-función en JavaScript

No sé si Brendan Eich es un amante de la física cuántica, pero al menos viendo algunas de las características, así lo parece. No solo tenemos el principio de incertidumbre de this si no que también tenemos el hecho de que en JavaScript un objeto puede comportarse como una función y viceversa, es decir una dualidad objeto-función.

Tomemos jQuery p. ej. Por defecto nos define el archiconocido $, con el cual podemos hacer algo como $(“#mydiv”), es decir, usarlo como una función, pero también podemos hacer $.getJSON(“…”), es decir, usarlo como un objeto. A ver como podemos conseguir esa dualidad es a lo que vamos a dedicar este post :)

La dualidad ya existente

La verdad… es que JavaScript ya viene con esa dualidad de serie… Todas las funciones de JavaScript se comportan a su vez como objetos (de hecho, en JavaScript las funciones son un tipo específico de objeto). O si no, observa el siguiente código:

  1. var f = function () {
  2.     console.log("i am a function, or an object?");
  3. }
  4.  
  5. console.log(typeof (f));
  6. console.log(f.toString());

El primer console.log, imprime “function”, dejando bien claro que f es una función. Pero luego observa que se está llamando al método toString de la función f. De la función en sí, no del valor devuelto por dicha función (lo que, ya puestos, generaría un error, pues f devuelve undefined). Así pues, las funciones tienen propiedades y métodos. Puede parecer chocante, pero en JavaScript los funciones, son también, objetos.

En JavaScript cada objeto tiene asociado su prototipo que es otro objeto (y dado que el prototipo es un objeto tiene asociado su propio prototipo, lo que genera una cadena de prototipos, que termina en un objeto llamado Object.prototype y que su prototipo es null).

Existe una propiedad, llamada __proto__, que nos permite acceder al prototipo de un objeto en concreto. Cuando creamos un objeto, usando object notation dicha propiedad se asigna a Object.prototype (como puedes comprobar en esa captura de pantalla de las herramientas de desarrollador de Chrome):

image

Las funciones, como objeto que son, tienen todas su propio prototipo que es… Function.prototype, que es por cierto el objeto que define las funciones call, apply y bind, que podemos llamar sobre cualquier función.

image

(Por si lo estás suponiendo, sí: el prototipo de Function.prototype es Object.prototype).

Entender bien la cadena de prototipado es fundamental, pues en ella se basa todo el sistema de herencia de JavaScript.

Ahora que ya vemos que las funciones en realidad son objetos, vamos a ver como podemos hacer como hace jQuery y colocar métodos propios en una función que definamos.

No nos sirve agregar métodos a Function.prototype: si lo hacemos esos métodos van a estar disponibles para todas las funciones y nosotros queremos que dichos métodos estén disponibles solo para una función en concreta (al igual que hace jQuery, que agrega métodos específicos pero solo a la función $).

Creando nuestra propia dualidad

Por extraño que parezca crear nuestra propia dualidad es muy sencillo, basta con el siguiente código:

  1. var f = function (name) {
  2.     return "Hello " + name;
  3. }
  4. f.foo = function () {
  5.     return "foo Utility method";
  6. }

Una vez tenemos esto podemos invocar a la función f, pero también a la función foo de la función f:

  1. var x = f("edu");
  2. var x2 = f.foo();

Ya tenemos a nuestra variable f, comportándose dualmente como una función y un objeto a la vez.

Por supuesto podemos refinar un poco esa técnica:

  1. var f = function (name) {
  2.     return "Hello " + name;
  3. }
  4. var fn = {
  5.     foo: function () {
  6.         console.log("Utility method");
  7.     }
  8. }
  9. Object.assign(f, fn);

Este código es equivalente al anterior, pero usa Object.assign (método de ES6) para copiar las propiedades contenidas en fn (el método foo) dentro del objeto (función) f.

Usando ES6 es muy fácil crearnos una función factoría que nos permita establecer un objeto con un conjunto de operaciones comunes a una función. Para ello podemos establecer este objeto como prototipo de la función (a su vez este objeto prototipo de la función debe “heredar” de Function.prototype para no perder las funciones que este provee).

  1. var factory = function (p, f) {
  2.     var fp = Object.create(Function.prototype);
  3.     Object.assign(fp, p);
  4.     Object.setPrototypeOf(f, fp);
  5.     return f;
  6. }

De este modo si tenemos un objeto cualquiera y queremos que todas sus operaciones sean heredadas por una función:

  1. var f = function () { return this; };
  2. factory({
  3.     dump: function () {
  4.         console.log('dump…');
  5.     }
  6. }, f);
  7. f.dump();

Ahora, la función f, además de los métodos definidos en Function.prototype (tales como apply o call) tiene también todos los métodos definidos en el objeto pasado como primer parámetro de factory, es decir el método dump.

Fácil y sencillo, ¿no?

Por cierto, ya puestos a divertirnos un poco. Cual es la salida del siguiente código si lo ejecutas en la consola JS del navegador?

  1. var f = function () { return this; };
  2. var obj = {
  3.     foo: f
  4. };
  5. factory({
  6.     unbind: function () {
  7.         return this.bind(this);
  8.     }
  9. }, f);
  10. console.log("f()", f());
  11. console.log("f.bind({a:10})()", f.bind({ a: 10 })());
  12. console.log("f.unbind()()", f.unbind()());
  13. console.log("obj.foo()", obj.foo());
  14. console.log("obj.foo.unbind()()", obj.foo.unbind()());

Piénsalo un poco con calma… si aciertas los valores de los 5 console.log eres de los que dominan el principio de incertidumbre de this 😉

Saludos!

Class library Packages (AKA ASP.NET5 Class Library) y Class Libraries “normales”

Una de las novedades de ASP.NET5 es la posibilidad de crear un proyecto de tipo Class Library. Este tipo de proyecto crea una librería de clases pero que utiliza el runtime de ASP.NET5 (DNX). En VS2015 se encuentran bajo el apartado de Web, aunque no tengan que ser usados necesariamente para proyectos web:

image

Teóricamente la salida de este tipo de proyectos no es una DLL, si no un paquete de NuGet. Vamos ahora a suponer el escenario que creamos una WebApi usando ASP.NET5 y tenemos un controlador como el siguiente (el código es lo de menos):

 

  1. [Route("api/[controller]")]
  2. public class BeersController : Controller
  3. {
  4.     // GET: api/values
  5.     [HttpGet]
  6.     public async Task<IActionResult> Get()
  7.     {
  8.         IEnumerable<Beer> beers = new[] {
  9.             new Beer {
  10.                 Id = 1,
  11.                 Name = "Estrella Damm"
  12.             },
  13.             new Beer {
  14.                 Id = 2,
  15.                 Name = "Moritz Epidor"
  16.             }
  17.         };
  18.         return new ObjectResult(beers);
  19.     }
  20. }

La clase Beer la tenemos definida en un proyecto Class Library (Package) llamado WebApi.Models, de forma que hemos agregado una referencia desde el proyecto WebApi hacia la Class Library. Eso lo podemos hacer directamente con VS2015 (de la forma “tradicional” usando Add Reference), lo que por debajo lo que hace es modificar el project.json, concretamente la sección “dependencies”:

  1. "dependencies": {
  2.   "Microsoft.AspNet.Mvc": "6.0.0-beta7",
  3.   "Microsoft.AspNet.Server.IIS": "1.0.0-beta7",
  4.   "Microsoft.AspNet.Server.WebListener": "1.0.0-beta7",
  5.   "Microsoft.AspNet.StaticFiles": "1.0.0-beta7",
  6.   "WebApi.Models": "1.0.0-*"
  7. },

Ahora, vamos a suponer que queremos crear una librería .NET para usar de cliente de nuestra WebApi en proyectos de escritorio. Y queremos reaprovechar las clases que están en WebApi.Models. El primer paso es crear una Class Library tradicional. Para ello elegimos .NET Framework 4.5 y creamos un proyecto de tipo Class Library. Llamémosle WebApi.Client.

Ahora si queremos reaprovechar las clases existentes en WebApi.Models para usarlas en esta librería, podemos intentar agregar una referencia desde la class library tradicional (WebApi.Client) hacia la librería WebApi.Models. Y cuando lo intentamos es cuando nos encontramos con un error:

image

Parece ser que no se puede agregar una referencia a un proyecto ASP.NET5 desde un proyecto .NET tradicional. Veamos como podemos conseguirlo.

Una manera es indicarle al proyecto ASP.NET5 que genere su salida. La idea es que esos proyectos ya no generan DLL tradicionales si no paquetes de NuGet (de ahí su nombre, precisamente). Por defecto esos paquetes no se generan, porque DNX no los requiere obligatoriamente en ejecución, pero si nos vamos a sus propiedades, pestaña build, podemos marcar la checkbox “Produce outputs on build”:

image

Ahora cuando compilemos WebApi.Models nos dejará el paquete de NuGet dentro de la carpeta artifacts/bin que cuelga de la carpeta de la solución. Allí nos encontraremos los paquetes de NuGet:

image

Si vas dentro de la carpeta dnxcore50 o dnx451 hay la DLL. Así, cuando hagas Add Reference, en lugar de irte a “Projects” y agregar una referencia de tipo “Project” (lo que termina con el error que hemos visto antes), le das a browse, navegas hacia la carpeta dnxcore50 y agregas una referencia a la DLL WebApi.Models.dll. Y con esto la referencia te aparecerá en la librería y podrás usar los tipos definidos en WebApi.Models:

image

Pero existe otra manera de obtener esa referencia y es aprovecharnos de que los proyectos ASP.NET5 generan paquetes de NuGet. Para ello primero necesitamos un “servidor local de NuGet” que es, básicamente, una carpeta. En mi caso se llama C:ufonuget. Es una carpeta normal y corriente, no tiene nada especial.

Ahora debes dar de alta esta carpeta como servidor de NuGet. Esto se hace a través de un fichero llamado NuGet.config que está en la raíz de la solución. Lo más fácil es que VS2015 modifique este fichero, yendo a Tools –> Options –> NuGet Package Manager –> Package Sources y agregar dicha carpeta como “package source”:

image

Esto automáticamente modifica el fichero NuGet.config a nivel de la solución:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <configuration>
  3.   <packageSources>
  4.     <!–To inherit the global NuGet package sources remove the <clear/> line below –>
  5.     <clear />
  6.     <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
  7.     <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
  8.     <add key="ufonuget" value="c:\ufonuget" />
  9.   </packageSources>
  10. </configuration>

Ahora debemos publicar el proyecto ASP.NET5 en el package source “ufonuget”. Para ello vamos a basarnos en las herramientas de línea de comandos de DNX. Abre una línea de comandos y vete a la carpeta raíz del proyecto WebApi.Models (la que contiene el fichero project.json). El primer punto es indicarle que se restauren todas las dependencias con “dnu restore”. Si este comando no te funciona (te dice que dnu no está reconocido) es que no tienes ningún framework DNX establecido por defecto. Ningún problema.

Si este es el caso teclea “dnvm list” y te saldran los distintos runtimes de DNX que tienes instalados:

image

El que tengas por defecto te saldrá marcado con un asterisco. En este caso no tenemos ninguno así que vamos a seleccionar el 1.0.0-beta7 para clr y x64. Para ello teclea “dnvm use 1.0.0-beta7 -arch x64 -r clr”. Esto, básicamente, agrega al path local (solo para esta línea de comandos) las herramientas del runtime de DNX que hemos elegido. Ahora sí, que ya puedes teclear “dnu restore”:

image

Ahora que ya tenemos las referencias necesarias para que se pueda compilar ese proyecto, vamos a empaquetarlo a c:ufonuget. Para ello vamos a usar el comando “dnu pack –out c:ufonuget”. Una vez haya terminado en la carpeta c:ufonuget deberíamos tener el paquete de NuGet.

Ahora volvemos a Visual Studio y usamos NuGet para agregar un proyecto a WebApi.Models a la class library WebApi.Client que hemos creado:

image

Obtenemos un error de que WebApi.Models no es compatible con .NET Framework 4.5. Eso es porque tenemos que añadir .NET4.5 como target de nuestra librería ASP.NET5. Para ello editamos el fichero project.json de WebApi.Models y añadimos “net45” dentro de la sección frameworks (dnx451 y dnxcore50 ya estaban):

  1. "frameworks": {
  2.   "dnx451": { },
  3.   "net45": { },
  4.   "dnxcore50": {
  5.     "dependencies": {
  6.       "Microsoft.CSharp": "4.0.1-beta-23225",
  7.       "System.Collections": "4.0.11-beta-23225",
  8.       "System.Linq": "4.0.1-beta-23225",
  9.       "System.Runtime": "4.0.21-beta-23225",
  10.       "System.Threading": "4.0.11-beta-23225"
  11.     }
  12.   }

Como no hay ninguna dependencia adicional para net45 no la colocamos. Ahora publicamos de nuevo el paquete nuget con “dnu pack –out c:ufonuget” y ahora si que podemos instalar el paquete NuGet:

image

¡Y eso es todo! Espero que os haya resultado interesante!

Saludos!

PD: Es posible que te preguntes que valores puede tener la sección “frameworks” además de dnx451, dnxcore50 y net45. Pues la verdad no he hecho pruebas, pero esta imagen extraída del post de Oren Novotny creo que contiene la respuesta:

Con esto (insisto que debo probarlo) se podrían atacar no solo librerías .NET si no de otras plataformas e incluso claro está PCLs.

Módulos en JavaScript… AMD, CommonJS

Con las aplicaciones web cada vez con mayor carga de cliente, y el uso cada vez mayor de sistemas de build en cliente como grunt o gulp, usar módulos para desarrollar en JavaScript es cada vez más habitual. Si todavía te descargas las librerías de sus páginas web y las incluyes una a una en tags <script/> es probable que este post te interese.

¿Qué es un módulo?

Llamamos módulo JavaScript a un código que de alguna manera es “auto contenido” y que expone una interfaz pública para ser usada. Esto no es realmente nuevo, el patrón de módulo ya hace bastantes años que se utiliza y no requiere más que algunos conocimientos de JavaScript para aplicarlo. El problema con los módulos en JavaScript no ha sido nunca el crearlos si no el de cargarlos. Puede parecer simple… de hecho, ¿no se trata solo de poner un tag <script />? Pues la realidad es que no, porque cargar un módulo implica que antes deben estar cargadas sus dependencias y por lo tanto debemos tener un mecanismo para definir esas dependencias y otro mecaniso para cargarlas al tiempo que cargamos el módulo deseado.

Es ahí donde entran en juego los distintos estándares de módulos que tenemos. Nos permiten crear módulos JavaScript, declarar las dependencias (es decir indicar de qué módulos depende nuestro módulo e incorporar la funcionalidad del módulo del cual dependemos) y cargar determinados módulos. Hay dos estándares usados hoy en día: CommonJS y AMD.

CommonJS

CommonJS es un sistema de módulos síncrono: es decir la carga de módulos es un proceso síncrono que empieza por un módulo inicial. Al cargarse este módulo se cargaran todas sus dependencias (y las dependencias de las dependencias, y las dependencias de las dependencias de las dependencias… y así hasta cualquier nivel de profundidad). Una vez finalicen todas esas cargas, el módulo inicial está cargado y empieza a ejecutarse. Definir un módulo en formato CommonJS es muy sencillo:

  1. var Complex = function (r, i) {
  2.     this.r = r instanceof Complex ? r.r : r;
  3.     this.i = r instanceof Complex ? r.i : (i || 0);
  4. }
  5. module.exports = Complex;

Supón que este código está en un fichero Complex.js. Este código define un módulo que exporta una función (constructora) llamada Complex. Observa el uso de module.exports para indicar que es lo que exporta el módulo. Todo lo que no pertenezca al exports son variables (y funciones) privadas del módulo. Ahora podríamos declarar otro módulo que dependiese de este módulo:

  1. var Complex = require('./complex');
  2. addComplex = function (ca, cb) {
  3.     return new Complex(ca.r + cb.r, ca.i + cb.i);
  4. }
  5. var math = {
  6.     add: function (a, b) {
  7.         if (a instanceof Complex || b instanceof Complex) {
  8.             return addComplex(new Complex(a), new Complex(b));
  9.         }
  10.         return a + b;
  11.     }
  12. }
  13. module.exports = math;

Este módulo (math.js) requiere el módulo complex.js (de ahí el uso de require), define un objeto math con un método y exporta dicho objeto. La función addComplex es privada al módulo.

Finalmente podemos crear un tercer módulo (main.js) que use esos módulos para sumar tanto números reales como complejos. Este va a ser nuestro módulo inicial:

  1. var Complex = require('./complex');
  2. var math = require('./math');
  3.  
  4. console.log(math.add(40, 2));
  5. var c1 = new Complex(40, 3);
  6. console.log(math.add(c1, 2));

Si ejecutamos el siguiente código mediante nodejs vemos como todo funciona correctamente:

image

Nodejs soporta módulos CommonJS de forma nativa, pero… ¿qué pasa con el navegador? Pues que necesitamos soporte de alguna herramienta externa. Una de las más conocidas es browserify que se instala como un paquete de node. Browserify es, a la vez, una herramienta de línea de comandos y un módulo CommonJS que podemos integrar con grunt o gulp. Si usamos la herrramienta de línea de comandos, se puede usar el comando browserify main.js > bundle.js para crear un fichero (bundle.js) que contenga el código de main.js y de todos sus módulos requeridos. Este fichero es el que usaría con un tag script.

Lo bueno de browserify es que solo debo indicarle el fichero inicial (en mi caso main.js). Él se encarga de ver los módulos necesarios y empaquetarlos todos juntos en un fichero. Usar browserify como herramienta de línea de comandos es posible (para ello basta con que lo tengas instalado como módulo global, es decir npm install –g browserify), pero no es lo más cómodo: lo suyo es tenerlo integrado dentro de nuestro script de build que tengamos con gulp o grunt. Por suerte browserify es también un módulo CommonJS por lo que podemos usarlo dentro de nuestro script de build. P. ej. el siguiente código muestra como usarlo mediante gulp:

  1. var gulp = require('gulp');
  2. var browserify = require('browserify');
  3. var source = require('vinyl-source-stream');
  4.  
  5. gulp.task('browserify', function () {
  6.     browserify('./main.js')
  7.         .bundle()
  8.         .pipe(source('bundle.js'))
  9.         .pipe(gulp.dest('./scripts'));
  10. });

Con esto basta con que ejecutes “gulp broswerify” para que browserify te deje en scripts un fichero bundle.js con el resultado de browserify. El único requisito es tener instalado (además de gulp y broswerify, obviamente) un módulo llamado vinyl-source-stream que se usa para pasar de streams basados en texto (los que usa browserify)  a streams de gulp.

Muchas de las librerías JavaScript (incluyendo incluso jQuery) tienen versión CommonJS lo que ayuda mucho a organizar tu código. Por supuesto se puede configurar browserify para que genere source maps o que aplique más transformaciones al código (p. ej. convertir código JSX de React en código JavaScript).

AMD

AMD es otra especificación de módulos JavaScript, cuya principal diferencia con CommonJS es que es asíncrona (AMD significa Asynchronous Module Definition). La implementación más conocida para navegadores de AMD es requirejs. Al ser asíncrona permite escenarios con carga de módulos bajo demanda (es decir cargar un módulo sólo si se va a usar), lo que puede ser interesante en según que aplicaciones.

Si usas requirejs no necesitas nada más: no es necesario que uses ninguna herramienta de línea de comandos o que crees tareas de grunt o gulp. Dado que requirejs implementa AMD va a ir cargando los módulos JavaScript de forma asíncrona. No tienes por qué crear un bundle con todos ellos.

La sintaxis para definir un módulo AMD es un poco más “liosa” que la sintaxis de CommonJS, pero tampoco mucho más. Empecemos por ver como sería el módulo AMD para definir el tipo Complex:

  1. define([], function () {
  2.     console.log('complex loaded…');
  3.     var Complex = function (r, i) {
  4.         this.r = r instanceof Complex ? r.r : r;
  5.         this.i = r instanceof Complex ? r.i : (i || 0);
  6.     }
  7.  
  8.     return Complex;
  9. });

Los módulos AMD empiezan con una llamada a define, que acepta básicamente dos parámetros: un array con las dependencias del módulo (el equivalente al require de CommonJS) y luego una función con el código del  módulo. Esa función devuelve lo que el módulo exporta (es decir, el return de la función equivale al module.exports de CommonJS). El módulo que define Complex no depende de nadie, así que el array está vacío. No ocurre lo mismo con el modulo math (fichero math_amd.js):

  1. define(['complex_amd'], function (Complex) {
  2.     addComplex = function (ca, cb) {
  3.         return new Complex(ca.r + cb.r, ca.i + cb.i);
  4.     }
  5.     var math = {
  6.         add: function (a, b) {
  7.             if (a instanceof Complex || b instanceof Complex) {
  8.                 return addComplex(new Complex(a), new Complex(b));
  9.             }
  10.             return a + b;
  11.         }
  12.     }
  13.     return math;
  14. });

Observa ahora como el módulo depende del módulo complex_amd. Eso significa que al cargarse este módulo, el módulo complex_amd (fichero complex_amd.js) debe estar cargado. Si no lo está requirejs lo cargará asincronamente, y cuando esta carga haya finalizado invocará la función que define el módulo. Observa ahora que la función tiene un parámetro. Este parámetro se corresponde con lo que exporta (devuelve) el módulo complex_amd del cual dependíamos. Básicamente, por cada elemento (dependencia) del array tendremos un parámetro en la función. Eso se ve todavía más claro en el modulo main_amd.js quie depende tanto de complex_amd como de math_amd:

  1. define(['complex_amd', 'math_amd'], function (Complex, math) {
  2.     console.log(math.add(40, 2));
  3.     var c1 = new Complex(40, 3);
  4.     console.log(math.add(c1, 2));
  5. });

Observa como hay dos parámetros en el array de dependencias y por lo tanto la función del módulo recibe dos parámetros. El array indica las dependencias y el parámetro de la función permite acceder a ellas.

Finalmente tan solo nos queda tener un html que cargue primero requirejs y una vez haya terminado, indique a requirejs que cargue el modulo main_amd.js y lo ejecute. Al cargar este módulo, requirejs cargará asíncronamente todas las dependencias. El código del fichero HTML es trivial:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <title></title>
  5. </head>
  6. <script data-main="main_amd" src="bower_components/requirejs/require.js"></script>
  7. <body>
  8. </body>
  9. </html>

El escenario “cargar requirejs y una vez haya terminado empieza a cargar el módulo indicado” es tan común que requirejs lo soporta a través del atributo data-main del tag script. Podemos ver en la pestaña network del navegador como realmente se cargan los tres módulos por separado:

image

¿Cuál usar?
La verdad es que AMD se acerca mucho más a la filosofía de la web que CommonJS. La carga asíncrona y on-demand es mucho más natural en la web que la carga síncrona que tiene CommonJS. Lo que ocurre es que actualmente solemos siempre crear un bundle de todos nuestros JavaScript, porque sabemos que es más rápido descargarse un solo fichero de 100Ks que 10 ficheros de 10Ks cada uno. Seguro que todos habéis oído que una de las normas básicas de optimizar una página web consiste en minimizar la descarga de ficheros. Los bundles de JavaScript, de CSS, los sprite-sheets y el uso de data-uris van todos por ese camino: cargar un fichero más grande antes que varios de pequeños. Si seguimos esa tónica perdemos la característica de carga on-demand y asíncrona de AMD (porque antes de ejecutar la aplicación hemos tenido que generar ese bundle). La verdad es que cargar los scripts on-demand no es algo que requieran la mayoría de aplicaciones (un escenario sería casos en que una aplicación quiere cargar scripts distintos en función de ciertos datos de ejecución, p. ej. scripts distintos por usuario).

Así parece que, actualmente, no haya una diferencia sustancial entre usar CommonJS y AMD si al final terminamos en un bundle. La cuestión puede reducirse a gustos personales o cantidad de módulos existentes en cada formato (a pesar de que es posible, con poco trabajo, usar módulos CommonJS bajo AMD) pero HTTP2 puede cambiar eso. HTTP2 convierte los bundles en no necesarios, ya que mejora el soporte para varias conexiones… bajo ese nueva prisma AMD parece ser una mejor opción que CommonJS. Pero HTTP2 es todavía muy nuevo, así que hasta todos los navegadores y servidores web lo soporten va a pasar algún tiempo… y cuando esté establecido, quizá y solo quizá, la duda de si usar CommonJS o AMD dejará de tenir sentido porque los módulos nativos de ES6 habrán tomado el relevo.

Saludos!

ASP.NET 5: Configuración

Una de las novedades de ASP.NET5 es su sistema de configuración. En versiones anteriores el sistema de configuración estaba muy atado al fichero web.config. En este fichero se guardaba tanto la configuración propia del programa (cadenas de conexión, appsettings o información adicional que suele estar en secciones de configuración propias) como información de configuración del propio runtime: tipo de seguridad, módulos a cargar, bindings de assemblies y un sinfin más de configuraciones.

En ASP.NET5 eso se ha simplificado mucho. Un tema importante es que ahora está claramente separada la configuración del framework que se realiza mayoritamente por código, la configuración del runtime que se delega en el fichero project.json y la configuración propia del programa que está en cualquier otro sitio. En este post nos centraremos solamente en la configuración propia del programa.

Configuración propia del programa (configuración de negocio)

La configuración propia toma la forma básica de un diccionario con claves que son cadenas y valores que son… cadenas. No tenemos una interfaz propia para cadenas de conexión o para las secciones propias de configuración. Para entendernos, sería como si todo fuesen appsettings. Es un mecanismo sencillo (si necesitas algo por encima de eso es fácil construirlo). El sistema por si mismo no nos ata a ningún formato de fichero (esa configuración puede estar en un json, un xml o lo que sea).

Aunque, es cierto, que el sistema de por si no nos ata a ningún esquema en concreto de nuestros datos, si queremos utilizar los métodos que son capaces de leer información automáticamente de un fichero, entonces si que debemos adaptarnos al esquema previsto, aunque es bastante ligero.

P. ej. esos tres ficheros contienen todos ellos la misma configuración:

  1.  
  2.   "smtp": {
  3.     "server": {
  4.       "user": "eiximenis",
  5.       "mail": "mail@domain.com"
  6.     },
  7.     "auth": {
  8.       "anonymous": "true"
  9.     }
  10.   }
  11. }

  1. <smtp>
  2.     <server>
  3.         <user>eiximenis</user>
  4.         <mail>mail@domain.com</mail>
  5.     </server>
  6.     <auth>
  7.         <anonymous>true</anonymous>
  8.     </auth>
  9. </smtp>

  1. [smtp:server]
  2. user=true
  3. mail=mail@domain.com
  4. [smtp:auth]
  5. anonymous=true

Los 3 ficheros definen las siguientes claves:

  • smtp:server:user –> Con valor “eiximenis”
  • stmp:server:mail –> Con valor “mail@domain.com
  • smtp:auth:anonymous –> Con valor “true”

En versiones anteriores esos 3 valores hubiesen ido, seguramente, en la sección<appSettings /> del web.config. La verdad es que usar el separador dos puntos (:) en las claves de appsettings es algo que ya era como un “estándard de facto”.

Para cargar esos ficheros usamos los métodos AddJsonFile(), AddXmlFile() o AddIniFile() del objeto ConfigurationBuilder, que se suele crear en el constructor de la clase Startup:

  1. public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
  2. {
  3.     // Setup configuration sources.
  4.     var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
  5.         //.AddJsonFile("config.json")
  6.         //.AddXmlFile("config.xml")
  7.         .AddIniFile("config.ini")
  8.         .AddEnvironmentVariables();
  9.     Configuration = builder.Build();
  10. }
  11.  
  12. public IConfiguration Configuration { get; set; }

El objeto Configuration básicamente expone un indexer para acceder a los valores de la configuración:

  1. var usermail = Configuration["smtp:server:user"];

Si quiero acceder a un valor de la configuración desde un controlador MVC puedo incorporar el objeto Configuration dentro del sistema de inyección de dependencias de asp.net 5:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3.     services.AddInstance<IConfiguration>(Configuration);
  4. }

Y ahora puedo añadir un parámetro IConfiguration a cada controlador que lo requiera.

El método GetConfigurationSection me devuelve otro IConfiguration pero cuya raíz es la clave que yo indique. Es decir dado el objeto Configuration que tenía si hago:

  1. var usermail = Configuration["smtp:server:user"];
  2. var smtpcfg = Configuration.GetConfigurationSection("smtp");
  3. var usermail2 = smtpcfg["server:user"];
  4. var servercfg = Configuration.GetConfigurationSection("smtp:server");
  5. var usermail3 = servercfg["user"];

Los valores de usermail, usermail2 y usermail3 son el mismo.

Configuración tipada

Este esquema de configuración es funcional y sencillo, pero a veces queremos usar objetos POCO para guardar nuestra propia configuración. Supongamos que tenemos la siguiente clase para guardar los datos del servidor:

  1. public class ServerConfig
  2. {
  3.     public string User { get; set; }
  4.     public string Mail { get; set; }
  5. }

Podemos mapear los datos que están en “smtp:server” con el siguiente código:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3.     services.Configure<ServerConfig>(Configuration.GetConfigurationSection("smtp:server"));
  4. }

Recuerda que GetConfigurationSection(“stmp:server”) me devuelve un IConfiguration que apunta directamente a esta clave y que por lo tanto tiene las dos claves “user” y “mail” que se corresponen con los nombres de las propiedades de la clase ServerConfig. Esta línea además incluye dentro del sistema de inyección de dependencias la clase ServerConfig así que ahora puedo inyectarla a cualquier controlador MVC que lo requiera:

  1. public HomeController(IOptions<ServerConfig> sc)
  2. {
  3.     var cfg = sc.Options;
  4.     var user = cfg.User;
  5. }

Observa, eso sí, que el parámetro no es un ServerConfig, si no un IOptions<ServerConfig> (eso es porque services.Configure incluye la interfaz IOptions<T> en el sistema de inyección de dependencias). Para acceder al objeto con la configuración usamos la propiedad Options.

Configuración anidada

Por supuesto el sistema soporta configuración anidada. Es decir, lo siguiente es correcto:

  1. public class SmtpConfig
  2.  {
  3.      public ServerConfig Server { get; set; }
  4.      public AuthConfig Auth { get; set; }
  5.  }
  6.  
  7.  public class ServerConfig
  8.  {
  9.      public string User { get; set; }
  10.      public string Mail { get; set; }
  11.  }
  12.  
  13.  public class AuthConfig
  14.  {
  15.      public string Anonymous { get; set; }
  16.  }

Y registrarlas de la siguiente manera:

  1. services.Configure<SmtpConfig>(Configuration.GetConfigurationSection("smtp"));

Y ahora podemos inyectar un  IOptions<SmtpConfig> en cualquier controlador que lo requiera:

  1. public HomeController(IOptions<SmtpConfig> sc)
  2. {
  3.     var cfg = sc.Options;
  4.     var user = cfg.Server.User;
  5. }

¡Sencillo y rápido!

Y hasta aquí este post sobre la configuración en ASP.NET5… espero que os haya resultado interesante!

Saludos!