Desarrollo rapido de apps con Ionic

lyonessDesde que surgió Ionic creo que la complejidad para desarrollar una aplicación para celulares y tablets se redujo muchísimo. Con saber un poco de html y javascript uno ya puede desarrollar una app completamente funcional y solo nuestra imaginación e ingenio nos ponen limites. Estoy viendo, por ejemplo, esta app de Lyoness. La verdad es que no se como esta desarrollada pero me imagino haciéndola con Ionic y es completamente factible.

Imaginemos lo siguiente, usamos WebView, con Angular hacemos algunos servicios que nos traigan las revistas, también usamos localstorage para guardar los settings y algunos datos para que la app este disponible cuando no tenga conexión a Internet, listo, ya tenemos nuestra app lista para funcionar.

Me parece muy importante eso de guardar datos para que estén disponibles cuando la app no tengo conexión a Internet. Eso es algo en lo que muchos de los desarrolladores que utilizan Ionic o Phonegap fallan. Con un par de minutos recorriendo Play Store se pueden encontrar multitud de comentarios diciendo que las apps no funcionan sin conexión a Internet, que solo esta mostrando una pagina web y cosas así.

Esta bueno esto de desarrollar apps de forma tan rápida. De hecho nos permite seguir eso del MVP (Minimum Viable Product o Producto viable mínimo) y sacar al mercado algo que se acerca a nuestra idea lo mas rápido posible. Pero también tenemos que asegurarnos de no caer en la tentación de sacar al mercado (aunque sea algo gratuito lo estamos sacando al mercado) apps que no sean usables y con bugs que arruinen la experiencia de usuario.

Particularmente creo que el desarrollo de aplicaciones híbridas llego para quedarse y lo vamos a ver cada vez mas. Ya no solo celulares y tablets, también en desktop y algunos dispositivos que todavía no imaginamos. Javascript se transformo en un verdadero lenguaje universal, y eso es gracias a los frameworks que surgieron a su alrededor, porque como lenguaje en si no es que facilite demasiado las cosas.

Contraseñas seguras para desarrolladores

Vamos a hablar un poco sobre como mantener las contraseñas seguras en nuestras aplicaciones. Empezaremos con una explicación básica de encripcion de contraseñas mediante funciones hash y luego seguiremos con el uso de sal (del ingles salt, donde seguramente encontraran mas información) tanto estática como dinámica, terminaremos con alguna locura de mi ocurrencia.

password

Contraseñas hasheadas

Una función hash (por ejemplo md5 o sha) es una que ante una entrada, que en nuestro caso va a ser una contraseña, genera un digesto de longitud fija. Por ejemplo md5 ante una entrada de cualquier longitud genera una cadena de 128 bits que es equivalente a 16 bytes. Esta función no tiene inversa, por lo que desencriptar una contraseña no es fácil.

Así por ejemplo si la contraseña elegida es “contraseña” la función md5 nos devuelve: 4c882dcb24bcb1bc225391a602feca7c

Y si nuestra contraseña es “123” nos devuelve: 202cb962ac59075b964b07152d234b70

Usando esta función podemos guardar en nuestra base de datos los valores hasheados de las contraseñas. Cuando un usuario intenta loguearse le aplicamos la función hash a lo que ingreso como password y luego comparamos con lo que tenemos guardado en la base de datos.

Si nuestra base de datos se ve comprometida estaríamos poniéndole una traba a los que quieren robar las contraseñas. El problema radica en que alguien con el suficiente tiempo y con un diccionario de contraseñas puede generar una tabla con los resultados de la función de hash, generalmente se conoce esto como una tabla rainbow.

De esta forma si se dispone de una tabla rainbow podemos comparar los valores hasheados para obtener el valor de la contraseña (mas adelante veremos que esto no es completamente cierto por eso de la colisiones de las funciones hash)…

saltHasheado y salado de contraseñas (salt estática)

El problema que nos generan las tablas rainbow puede paliarse con el uso de una cadena de caracteres que se le agregue a cada contraseña antes de aplicarle la función de hash. Esa cadena de caracteres es lo que se conoce como la sal (o el salt). Veamos un ejemplo:

Nuestra contraseña es “contraseña” como la que vimos anteriormente, ahora vamos a agregar nuestra sal digamos que es algo tan básico como (123). Si hacemos md5(123+contraseña) el resultado es: 46eb9acec1a2dfd3217b786122697d69. El valor obtenido de la función de hash puede estar presente en una tabla rainbow pero nuestro atacante no debería poder saber que parte corresponde a la contraseña y que parte a la sal. Sobre todo si tenemos en cuenta las colosiones que puede generar esta funcion.

Colisiones en funciones de hash

Se llama colisiones a diferentes entradas que generan el mismo resultado de la función de hash. Si solo usamos una funcion de hash no necesitamos obtener la contraseña verdadera sino que con obtener una cadena de caracteres que al aplicarle la función nos devuelva el mismo resultado nos alcanza para loguearnos.

Si nuestro atacante obtiene un valor que pueda utilizarle tiene que poder separar la parte de la sal y si es por una colisión esto se vuelve imposible.

Contraseñas hasheadas con salt (salado dinamico)

El problema del punto anterior es que si el atacante obtiene el valor del salt puede generar una tabla rainbow especifica para atacar nuestra aplicación. Teniendo un diccionario lo suficientemente grande al cual se le concatena la sal a cada entrada se puede obtener la correlación de las contraseñas originales con el valor del hash resultante.

Para evitar esto podemos utilizar valor de hash dinámicos para cada usuario. Podemos guardar (en la misma base de datos o en otro lado si se quiere mayor seguridad) un valor de salt diferente para cada usuario, usando una función que devuelva una cadena random que generamos en el momento del registro.

Usando esta técnica al momento de loguearse un usuario tomamos la contraseña que ingreso, consultamos la base de dato y calculamos el valor del hash resultante de concatenar la contraseña ingresada + la cadena guardada.

Si guardamos la sal en la misma base de datos podemos pensar que nuestras contraseñas serán casi tan vulnerables como en el primer ejemplo, la realidad es que el atacante debería generar una tabla rainbow para cada usuario si quiere obtener todas las contraseñas. Esto es, por ahora, computacionalmente inviable para el común de los mortales, pero alguien con el suficiente interés, y con el poder de calculo suficiente, podría vulnerar la mayoría de nuestras contraseñas.

Agregando pimienta

pimientaPara asegurar mas nuestra contraseña podemos utilizar un poco de ingenio. Por ejemplo combinar mas de 1 salt. Podemos tener un salt dinámico para cada usuario y uno estático que no se guarde en la base de datos. También podemos utilizar valores dinámicos que no se identifiquen como parte de la contraseña.

Por ejemplo podemos utilizar como entrada de nuestra función de hash: un salt estático guardo como variable de nuestra aplicación (no en la base de datos) + contraseña del usuario + salt dinámico + id de usuario. Así nuestra aplicación tendría una capa extra de protección presente únicamente en la lógica.

Incluso podemos aplicar la función hash recursivamente para agregar todavía mas seguridad, por ejemplo:

Allí estaríamos hasheando una contraseña hasheada agregando un nivel de complejidad extra. Incluso podríamos poner esto dentro de un “for” para aplicarlo la cantidad de veces que queramos haciendo prácticamente imposible que un atacante pueda obtener todas las contraseñas que tenemos alojadas en el sitio.

Evitar ataques de fuerza bruta

Todo muy lindo ¿no? pero también tenemos que asegurar cosas mas básicas, por ejemplo debemos evitar los ataques de fuerza de bruta. Si tenemos todo lo anterior pero le permitimos al atacante probar miles de contraseñas sin ningún tipo de control nuestra aplicación seguiría siendo insegura. Para ello podemos aplicar limitaciones como el clásico ha ingresado 5 veces erróneamente la contraseña debe esperar 15 minutos antes de volver a intentarlo.

Y… ¿Ustedes como aseguran sus contraseñas?

 

A dieta

Tengo casi 30 años soy gordo y fumo en el preocupacional que me hice hace poco la balanza acusó 135 kilos. Creo que es hora de hacerse cargo y tomar cartas en el asunto. Por eso mismo estoy comenzando la dieta. Casi toda mi vida hice dieta. Los últimos 20 años fueron un sin fin de bajadas y subidas de peso. Aunque los últimos fueron sobre todo subidas.
Ojo no tengo problemas con ser gordo, estéticamente hablando, pero estoy comenzando a notar como me afecta la  salud. Dolores de espalda, contracturas, agitamiento… Son cosas que le achaco a la gordura.
Mi meta es bajar 40 kilos en un año. No quiero, y creó que no podría lograrlo, bajar mucho más que eso. Con estar en las dos cifras ya estaría muy contento, hace muchos años que no estoy en menos de 100 kilos.
El cambio de trabajo no me va a permitir ejercitarme mucho. No por el trabajo en si, lo que jode es el viaje, dos horas de ida y dos horas de vuelta. Para los primeros kilos no va a significar un gran problema: con solo cambiar la alimentación creo que puedo bajar unos 10 o 15 kilos sin problema. Ya veré como hago cuando necesite gimnasia para seguir bajando.
En fin este año trae muchas cosas nuevas para mi… Espero poder lograr todo lo que me propuse

Consegui trabajo

Hace un mes y medio festejaba que me habia recibido… hace un mes publicaba que estaba buscando trabajo. Y puedo decir que ya lo consegui. El puesto que quiero, en la empresa que quiero, con los jefes que quiero. Mejor no me podria haber salido. En marzo empiezo.

No me quejo de mi actual trabajo. Fueron casi 8 años, me dio de comer, me permitio recibirme y colaboro en gran media con mi desarrollo como persona. Pero es una etapa que considero terminada. Conoci mucha gente interesante, algunos incluso puedo considerarlos amigos, pero es hora de seguir mi camino.

Me espera un mundo completamente nuevo, estoy contento con el cambio, algo asustado tambien, no es lo mismo trabajar para el estado que trabajar para una empresa privada. Y eso que no soy el tipico empleado publico.

Hay mucha gente que deposito su confianza en mi, el primero de todos el que me dio su recomendacion para que entre a trabajar. No tengo pensado fallarle a nadie, pienso dar el 100% como lo hago siempre, como lo hago en todos lados, pero es una responsabilidad enorme.

En fin… ya tengo nuevo trabajo y me estoy despidiendo del actual…

Usando ControllerAs en AngularJS

Estaba leyendo a John Papa, particularmente su guia de estilo para AngularJS. Según dicen algunos seguir esta guía hará que el paso a Angular 2.0 no sea tan difícil. Después de leerlo completamente ademas de eso considero que seguir esta guía nos devuelve un código mucho mas entendible. Uno de los puntos que mas me gusta es el de usar Controller As para evitar el uso de $scope. Así que agarre el ejemplo de upload de imágenes en angular y me puse manos a la obra para modificar el controlador.

Lo primero fue definir el controllerAs en el routeProvider y luego definir la función del controlador, no dejarla como una funciona anónima. Para ello solo debíamos hacer algunos cambios a la forma en que llamábamos al controlador, aproveche y cambie también la forma en que se hace la inyección de dependencias siguiendo lo que se recomienda John, de esta forma me quedo algo asi:

La definición de la ruta:

Notese el controllerAs… con esto y con algunos cambios en el controlador vamos a acceder a las variables mediante {{vista.loEsteDefinido}} quedando, creo yo bastante bien. Ademas nos ayuda a evitar colisiones cuando se superponen controladores en una vista.

En donde definí el controlador solo tengo lo siguiente:

Básicamente le estoy diciendo que el controlador VistaCtrl sera la funcion VistaCtrl. Ahora solo nos queda definir la función y hacer la inyección de dependencias:

La primer linea es la inyección y la segunda la definición de la función, como seguramente ya notaron. Entonces en todos los lugares en donde yo definia $scope.variable lo cambie por vm.variable (vm es por viewModel)…  Por ejemplo la función que envía la imagen quedo definida así:

Por ultimo en la vista ya no se accede con el nombre definido con $scope… ahora para acceder a la función o a cualquier otra variable definida dentro del controller utilizo vm.variable…

El uso de vm=this; es interesante, ya que se utiliza para evitar colisiones cuando definimos funciones dentro del controller lo que puede hacer que se pise el this…

Pueden ver el código en el repositorio de github… Allí voy a seguir subiendo algunas cosas según valla aprendiendo y teniendo tiempo de aplicar los cambios.

¿Que sigue?

Bueno… separar cada cosa en su propio archivo, no me terminaba de gustar la forma en que armaba todo angular seed y luego de leer la guia creo que me inclino mas por un archivo para cada cosa.

Modificar la directiva para que siga la misma convención de definir la función correctamente. Y hacer lo mismo con los servicios y factorys, que, de hecho, no se utilizaron la primer versión del upload de imágenes, pero que pretendo usarlas para dejar los controllers mas claros.