Slashpub

vrubert's blog

Autenticando Usuarios Google en Una Aplicación node.js

Por fin saco un rato de tiempo para documentar lo que voy aprendiendo con node.js, en este caso tenía en mente realizar una sencilla demo de autenticación de usuarios contra el backend de usuarios de Google, de manera que pueda reaprovecharse para otros proyectos. Básicamente, lo que se pretende es crear un página sencilla, con un botón de Login donde el usuario pueda autenticarse, pero sin mantener una base de datos de usuarios locales, sino que delegaremos la autenticación a Google haciendo uso de su infraestructura OpenId

La pila tecnológica utilizada en este caso esta basada en Node.js:

  • Express como framework de desarrollo web.
  • Mongodb como base de datos de persistencia.
  • Passport como middleware de autenticación.
  • Mongoose como librerías de acceso a la DB.
  • Jade como sistema de plantillas.
  • Jquery como librería javascript para manipulación del DOM.
  • Twitter Bootstrap como framework de creación de interfaces de usuario.

Este es el proyecto en github que implementa esta sencilla utilidad, sólamente hay que bajarlo y seguir un par de pasos para tenerlo funcionando, serviría como código base para entender cómo funciona la autenticación en node.

https://github.com/tombatossals/node-openid-auth-sample.git

Sirviendo Nuestro Proyecto Node.js Detrás De Un Servidor Web Nginx

Realizando un proyecto en node.js y viendo cómo las cosas empiezan a cuajar, te vas dando cuenta de necesidades adicionales a la propia programación orientada a eventos, como por ejemplo, servir tus páginas desde el puerto 80.

El servidor http que implementa node.js es rápido y eficiente, pero no siempre podemos arrancarlo en el puerto 80. Puede que no tengamos un usuario con los privilegios necesarios, puede que ya tengamos otras ṕaginas en esa máquina que tienen que seguir funcionando, o puede que necesitemos características propias de un servidor web y que no vienen incorporadas en el servidor web de node.

En esos casos mejor delegar el frontal en un servidor web también rápido y eficiente como es Nginx. Pongo la receta a utilizar para servir el contenido de nuestro servicio Node (escuchando en el puerto 3000) en una ruta de nuestro servidor web:

Sección http de Nginx:

1
2
3
upstream app_miservicionode {
    server 127.0.0.1:3000;
}

Seccion server de Nginx:

1
2
3
4
5
6
7
8
9
location /ruta {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_pass http://app_miservicionode;
        proxy_redirect off;
}

Y listo, con esto habilitamos un proxy de Nginx que redirigirá las peticiones al puerto 80 de nuestro servidor, al puerto 3000 del interfaz local (127.0.0.1), que es donde estará corriendo nuestro servicio node.js.

En una siguiente entrada veremos como conseguir que nuestro servicio node este siempre funcionando en el sistema.

Rotación De Imágenes en Un Canvas

Veamos un ejemplo de desarrollo en un canvas HTML, en este caso trabajaremos con una imagen a la cual le aplicaremos una animación consistente en rotar la imagen.

Veamos la demo antes que nada (mejor visitar el enlace que os propongo abajo para que os funcione el botón de fullscreen):

En esta demo podemos observar 3 novedades puestas en práctica:

  • Una animación realizada en base a la rotación una imagen de un sol a 60fps.
  • Un monitor que contabiliza el número de frames obtenidos en el renderizado, y los milisegundos necesarios para procesar cada nuevo frame.
  • Un botón que nos permite realizar un fullscreen de una zona de nuestra página.

Vayamos por partes, de fácil a difícil.

stats.js

El monitor de frames lo podemos incorporar en cualquiera de nuestros proyectos de una manera extremadamente fácil utilizando el código del proyecto stats.js.

Fullscreen API

Tal y como comenté en el anterior post, la Fullscreen API nos permite focalizar la atención del usuario maximizando una zona de nuestra web a pantalla completa. La implementación que véis en este código funciona tanto en Chrome como en Firefox. A destacar el código CSS necesario para unificar la manera de maximizar de los dos navegadores.

Canvas Image Rotation

Finalmente, comentar que en el código veremos en funcionamiento una de las utilidades incorporadas recientemente en los navegadores como es el control de frames mediante la función requestAnimationFrame (todavía en desarrollo en algunos navegadores), así como la manera de realizar una rotación de imagen sobre un canvas, se ilustra perfectamente en esta imagen:

Image rotation on canvas

El código fuente es sencillo y se explica por si mismo: script.js.

Referencias:

API Fullscreen Para Navegadores

La API fullscreen para navegadores es una característica (todavía en fase experimental) que ya implementan las nuevas versiones de Chrome. En Firefox 9 viene implementada pero no está habilitada, a partir de la versión 10 ya vendrá activada por defecto.

El uso de la API es muy simple, se resume en lo siguiente: Podemos coger un bloque multimedia de la web que estamos desarrollando (un video, una imagen, un canvas) y ampliarlo a pantalla completa para enfocar la atención del usuario a esa zona de nuestra web, consiguiendo así que el visitante se concentre y visualice mejor ese elemento.

Las llamadas a la API son muy concretas. Para pasar a pantalla completa un elemento, llamamos (vía javascript) a la función RequestFullScreen desde el propio elemento. Y para volver al modo normal, llamamos a la función CancelFullScreen desde el elemento document.

1
2
3
4
5
div.RequestFullScreen(); // Solicita la activación de pantalla completa 
                         // sobre el elemento div que queramos

document.CancelFullScreen(); // Cancela la pantalla completa y vuelve al modo
                             // de visualización normal

Dispondremos también del evento fullscreenchange que se dispara cuando se detecta el paso al modo pantalla completa. Ejemplo:

1
document.addEventListener('fullscreenchange', on_fullscreen_change);

Finalmente, tenemos una propiedad de sólo lectura que nos informa si el navegador está en modo fullscreen.

1
document.FullScreen // tendrá un valor true o false

Para terminar, simplemente comentar que mientras se estandariza la API, cada navegador la implementa por su cuenta, y como viene siendo habitual, necesitaremos llamar a estas funciones de manera diferente según el navegador (mozRequestFullScreen, webkitCancelFullScreen, etc.).

Podéis ver mejor todo esto en la demo siguiente: http://dev.micronautas.com/demos/fullscreen/fullscreen.html

En la versión actual de Firefox (v9.0.1) tendréis que habilitar la variable full-screen-api.enabled entrando en el about:config para poder probarlo.

Enlaces de interes:

Herramientas Linux Bajo Entorno Windows

De vez en cuando me surge la necesidad de trabajar en un entorno Windows, y la verdad es que se echan de menos determinadas herramientas GNU-Linux de las que adolece cualquier sistema operativo Microsoft.

En esos casos lo primero que hago es instalarme CygWin, bajando un simple instalador y siguiendo un wizard siguiente-siguiente tendremos disponibles las principales herramientas Unix (cut, grep, find, awk, sort, cat, ls, etc.), pudiendo a su vez añadir más utilidades al estilo de un instalador de paquetes gráfico (por ejemplo podremos instalar vim, git, mercurial, etc.).

Sólamente instalarlo, abrir una línea de comandos y ver un bash en funcionamiento ya reconforta.

Además, si la consola clásica de Windows no nos convence, podemos utilizar una consola más usable como es un terminal de putty adaptado a cygwin: puttycfg

Os cuento cómo lo configuro:

  • Descargo puttycfg, y pongo un acceso directo al ejecutable en la barra de acceso rápido de Windows:

  • Arranco putty por primera vez y guardo una nueva sesión llamada bash con los siguientes datos:

  • Edito el acceso directo de la barra de acceso rápido y le pongo un sufijo al comando ejecutable: “-load bash”.

  • Listo, al pulsar el acceso directo se me abre una consola similar a la de Linux, todo un lujo para el entorno en el que estamos. :)

Girasol Animado Con Canvas Y Javascript

La mejora de rendimiento en las animaciones del elemento canvas que se ha producido en los navegadores web últimamente ha sido espectacular. Trasteando con el requestAnimationFrame, y desempolvando algunos algoritmos matemáticos, se pueden conseguir cosas chulas, como ésta que he portado directamente de una demo del lenguaje de programación Dart.

Aplicación Rails en Servidor Web Nginx

Una aplicación rails funciona con su propio servidor web, normalmente en el puerto 3000 del sistema. Si queremos servir la aplicación en el puerto 80 estándar a través de Nginx, deberemos configurar este servidor web para que actúe de proxy hacia la aplicación rails.

Esta es la receta para el archivo nginx.conf:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
upstream rails.miservidor.com {
    server 127.0.0.1:3000;
}

server {
    listen   80;
    server_name rails.miservidor.com;
 
    access_log /var/www/rails.miservidor.com/log/access.log;
    error_log  /var/www/rails.miservidor.com/log/error.log;
    root       /var/www/rails.miservidor.com
    index      index.html;
 
    location / {
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  Host $http_host;
        proxy_redirect    off;
        try_files /system/maintenance.html $uri $uri/index.html $uri.html @ruby;
    }
 
    location @ruby {
        proxy_pass http://rails.miservidor.com;
    }
}

Primeros Pasos Con Git

Antes de empezar cualquier proyecto Git en una nueva máquina deberemos configurar algunas opciones globales que nos facilitarán nuestro trabajo con el control de versiones. Veamos 3 opciones básicas:

1
2
3
$ git config --global user.name "Peter Pan"
$ git config --global user.email peter.pan@nuncajamas.com
$ git config --global color.ui true

Las dos primeras opciones establecen nuestro nombre completo y dirección de correo que utilizaremos para identificar nuestros commits al repositorio. La tercera opción nos vendrá muy bien para colorear los mensajes que nos muestra Git por la salida estándar.

Estas tres opciones configuradas desde línea de comandos se traducen en una serie de directivas almacenadas en el archivo de configuración .gitconfig:

1
2
3
4
5
6
$ cat $HOME/.gitconfig 
[user]
    name = Peter Pan
    email = peter.pan@nuncajamas.com
[color]
    ui = true

Instalando Ruby 1.9.2 Mediante Rvm

Al probar proyectos rails nos encontramos con el problema de las múltiples dependencias de otras librerías que tienen cada uno de ellos, y la dificultad que eso conlleva para mantener nuestro sistema operativo al día, por no decir nuestro alojamiento.

Lo mejor para estos casos es utilizar RVM, que nos instalará un entorno ruby propio para nuestros proyectos, independizándonos así de los paquetes ya instalados en el sistema.

Enlace: http://beginrescueend.com/

Receta de instalación de Ruby 1.9.2 con RVM:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Install RVM
bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load
RVM function' >> ~/.bash_profile
source ~/.bash_profile

# Install OpenSSL&ZLIB
rvm pkg install zlib
export C_INCLUDE_PATH=$HOME/.rvm/usr/include
rvm pkg install openssl

# Install Ruby
rvm install 1.9.2 --with-zlib-dir=$rvm_path/usr
--with-openssl-dir=$rvm_path/usr

http://pastie.org/2923827

Octopress

Octopress es un sistema de blogging diferente a todo lo visto hasta ahora. Para empezar, va a contracorriente de las modas: ¿desde cuándo para publicar en un blog hay que tener nociones de markdown, git, algo de ruby y rsync? Pues con Octopress las cosas son así.

La ventaja principal: editas un archivo de texto formateado con Markdown, regeneras las páginas, haces un rsync y tu blog se publica de una manera estática, es decir, no necesitas ni PHP, ni Mysql, ni un software abierto a posibles fallos, para algo tan simple como escribir una entrada.

A mi me sirve, principalmente porque en lepus.uji.es sólo podemos poner contenido estático, asi que…

1
2
$ rake generate
$ rake desploy