Compartir a través de



Agosto de 2015

Volumen 30, número 8

Servicios móviles de Azure - Servicios móviles de Azure: un fantástico back-end para AngularJS

Por Jonathan Miller

AngularJS es un marco excelente para crear aplicaciones de JavaScript para web y móviles. Es muy eficaz, pero viene con algo de una curva de aprendizaje. Para empezar, he leído blogs y libros y he visto cursos en vídeo, que son excelentes para aprender las características de cliente, como formularios, enrutamiento y validación. Lamentablemente, los temas del cliente siempre parecen hacer sombra a las preocupaciones de back-end. La mayoría de los recursos de aprendizaje casi no tratan estos temas en absoluto. Un curso usó el servicio $httpBackend de Angular casi en exclusividad. $httpBackend es una excelente manera de generar emulaciones para pruebas, pero no está pensado para conservar datos para una aplicación de producción. Otro recurso usó un producto de código abierto denominado deployd (deployd.com), que ofrece una manera rápida y sencilla de obtener un servidor de back-end de la API/REST activo y en funcionamiento. La descarga de Deployd es gratuita y se puede ejecutar en un servidor o máquina de desarrollo. Resulta excelente para modelar y probar API de REST. Una vez más, el problema de nuevo es qué hacer en producción. En un entorno de producción, tengo que exponer un servidor REST/JSON a Internet para que lo use la aplicación AngularJS, pero no quiero estar hospedando y administrando servidores en Internet. Necesito poder lanzar nuevas aplicaciones de manera rápida y escalar con rapidez según sea necesario. Necesito seguridad integrada sin mucha complejidad. Es necesario poder configurar las API JSON/REST para almacenar los datos de aplicación. Además, necesito que todos estos asuntos sean sencillos de aprender y de integrar con mi aplicación. Por suerte, en mi estudio he descubierto que Microsoft ya ha resuelto estos problemas. En este artículo le mostraré cómo integrar el back-end de los Servicios móviles de Azure con un front-end de AngularJS.

Servicios móviles de Azure (AMS) es realmente un back-end en una caja. Reúne todas las partes de back-end necesarias para una aplicación de producción y tiene varias atractivas características:

  • Ofrece almacenamiento en la nube muy rápido y redundante.
  • Hace que se pueda acceder a las tablas de creación a través de REST/JSON de una manera muy sencilla.
  • Ofrece autenticación y seguridad integrada a los proveedores de inicio de sesión populares como Microsoft, Google, Facebook y Twitter.
  • Empieza de manera gratuita y puede escalar para aplicaciones de alta demanda.
  • Facilita la validación del lado del servidor.
  • Permite tanto el extremo de JavaScript como el de .NET. Microsoft ha simplificado mucho el aprovisionamiento de un sitio de SMS y su integración con casi cualquier plataforma de cliente.

Mi aplicación de notas Angular

Para demostrar cómo conectar AngularJS y AMS, voy a reunir una aplicación muy sencilla de notas de Angular. Esta aplicación será una sola página y constará de una lista de notas. Cada nota tendrá un botón para eliminar junto a ella. También habrá un cuadro de texto para agregar una nueva nota a la lista. En la Figura 1 se muestra el aspecto que tendrá mi aplicación de notas de Angular.

Aplicación de notas de Angular
Figura 1 Aplicación de notas de Angular

Para esta aplicación, usaré Visual Studio 2013 Update 4 y la cuenta de Azure que recibo con mis ventajas de MSDN. Para poder continuar, primero debe crear una nueva aplicación web de ASP.NET. Elija la aplicación vacía y ninguna opción, como se muestra en la Figura 2.

Creación de un proyecto de ASP.NET vacío
Figura 2 Creación de un proyecto de ASP.NET vacío

Ahora debe agregar las bibliotecas de AngularJS y Bootstrap; por tanto, agregue los paquetes de NuGet para Angular.Core y Bootstrap.

Para crear la vista inicial, agregue una nueva página HTML a la raíz del proyecto denominada notes.html. Modifique el HTML para que coincida con la Figura 3. Observe que hace referencia a Angular y Bootstrap. También tiene la etiqueta ng-app, que indica a Angular que procese esta página. Por último, tiene una sección de cuerpo con una etiqueta ng-controller para el controlador que voy a crear más tarde. He esparcido algunas clases de arranque para que parezca interesante. No son obligatorios y se pueden ignorar.

Figura 3 Vista HTML inicial

<html ng-app="notesApp">
<head>
  <title>Angular Notes</title>
  <link type="text/css" rel="stylesheet" href="Content/bootstrap.css" />
  <script src="Scripts/angular.js"></script>
  <script src="notesCtrl.js"></script>
</head>
<body ng-controller="notesCtrl as vm">
  <div class="page-header text-center">
    <h1>
      <span class="glyphicon glyphicon-cloud" aria-hidden="true"></span>
      <span style="padding-bottom:10px">Angular Notes</span>
    </h1>
  </div>
</body>
</html>

Para agregar la lista de notas, dentro de la sección del cuerpo, agregue un nuevo div a la parte inferior, como se muestra en la Figura 4. Este div recorrerá en iteración la lista de notas y mostrará una fila de tabla para cada una de ellas. También coloca un botón para eliminar en cada fila. La etiqueta clave que realiza este trabajo es la etiqueta ng-repeat, que recorre en iteración la matriz de notas en el controlador.

Figura 4 Adición de la lista de notas

<div class="container">
  <div class="panel panel-default">
    <table class="table table-striped">
      <tr class="list-group" ng-repeat="note in vm.notes">
        <td>
          {{note.notetext}}
          <button class="btn btn-xs btn-danger pull-right"
            ng-click="vm.deleteNote(note)">
            <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
          </button>
        </td>
      </tr>
    </table>
  </div>
</div>

Por último, para crear un nuevo cuadro de nota, agregue un último div a esta vista para que un usuario pueda crear una nota nueva. Colóquelo encima del div para la tabla de notas. En el código siguiente, observe que el contenido del cuadro de entrada está vinculado a datos para vm.addNoteText y que al hacer clic en el botón o presionar Entrar se llamará al método vm.addNote en el controlador:

<div class="input-group" style="padding-bottom:15px">
  <input type="text" class="form-control" ng-model="vm.addNoteText"
    placeholder="new note" ng-keypress="($event.which === 13)?vm.addNote():0" />
  <span class="input-group-btn">
    <button ng-click="vm.addNote()" class="btn btn-success">Add Note</button>
  </span>
</div>

Para agregar el controlador, cree un nuevo archivo JavaScript en la raíz del proyecto denominado notesCtrl.js. En la Figura 5 se muestra el código para todo el controlador. Consta de la matriz de notas iniciales que se mostrará, la función addNote que agrega un elemento a la matriz y la función deleteNote que quita una nota de la matriz. Asegúrese de que hay una referencia a este script en la vista de notes.html.

Figure 5 Adición del controlador

angular.module('notesApp', [])
  .controller('notesCtrl', function () {
    var vm = this;
    vm.addNoteText = '';
    vm.notes = [
      { "notetext": "Fix driveway" },
      { "notetext": "Replace roof" },
      { "notetext": "Fix dryer" },
      { "notetext": "Tear out deck" },
      { "notetext": "Add electricity to garage" }
    ];
    vm.addNote = function () {
      if (vm.addNoteText !== '') {
          vm.notes.push({ "notetext": vm.addNoteText });
          vm.addNoteText = '';
      }
    }
    vm.deleteNote = function (note) {
      vm.notes.splice(vm.notes.indexOf(note), 1);
    }
  });

En este punto, finalizará la aplicación Angular principal. La ejecución de la página muestra una lista de notas. Hacer clic en la X roja junto a una nota la elimina. Al escribir una nueva nota en el cuadro de texto y hacer clic en Agregar nota se agregará a la lista. Sin embargo, hasta ahora, la lista solo está en memoria. La actualización de la página recuperará la lista original y se perderán todos los cambios. Movamos el almacenamiento de datos fuera de la memoria a la nube.

Almacenamiento de datos en Servicios móviles de Azure

Voy a cambiar el mecanismo de almacenamiento para las notas. En lugar de utilizar una matriz estática en memoria, voy a cargar y guardar mis notas desde AMS.

En el portal de Azure, cree un nuevo servicio móvil de Azure. Asegúrese de que usa el back-end de JavaScript. Luego haga clic en la pestaña Datos dentro del servicio móvil y cree una nueva tabla de datos como se muestra en la Figura 6.

Creación de una nueva tabla de notas
Figura 6 Creación de una nueva tabla de notas

Luego, para agregar la columna de texto de nota, agregue una columna de cadena denominada notetext a la tabla de notas.

Ahora necesita obtener la clave de aplicación. En la página principal del Portal de Azure de servicios móviles de Azure, verá un botón etiqueta Administrar claves. Haga clic en esto para recuperar la clave de aplicación y guardarla en algún lugar para más tarde. La aplicación Angular la necesitará para acceder a AMS.

Para que AMS trabaje en la aplicación Angular, debe agregar dos referencias de script a la vista Notes.html. La primera es para la biblioteca de JavaScript ofrecida por Microsoft para Servicios móviles de Azure. La segunda es un servicio de estilo Angular que ajusta la biblioteca de Microsoft. La principal ventaja de esta biblioteca es que amplía la biblioteca de Microsoft JavaScript para AMS y ofrece promesas e interfaces de estilo Angular. Encontrará un código de ejemplo excelente en GitHub en bit.ly/1po76vI.

Asegúrese de que estas nuevas entradas aparecen entre las referencias de angular.js y notesCtrl.js, de manera similar a lo siguiente:

<script src="Scripts/angular.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/mobileservices/MobileServices.Web-1.1.2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-azure-mobile-service/1.3.4/angular-azure-mobile-service.min.js"></script>
<script src="notesCtrl.js"></script>

Para hacer referencia a Servicios móviles de Azure en el controlador, cambie la primera línea de NotesCtrl.js y agregue una dependencia a ‘azure-­mobile-service.module’:

angular.module('notesApp', ['azure-mobile-service.module'])

Agregue una constante a la parte inferior del archivo notesCtrl.js con la dirección URL del sitio móvil de Azure y la clave de aplicación recuperada anteriormente. La biblioteca de AMS las usará para acceder al sitio de AMS:

angular.module('notesApp').constant('AzureMobileServiceClient', {
  API_URL: "https://angularnotes.azure-mobile.net/",
  API_KEY: "gkwGJioLD3jNxrAX6krXh6jVk6SFkeQr",
});

Ahora reemplace el código en el controlador que establece vm.notes en una matriz estática con datos recuperados de AMS. Este código recupera toda la tabla de nota e incluye el resultado en la matriz de vm.notes:

Azureservice.query('notes', {})
.then(function (items)
{
  vm.notes = items;
});

A continuación, cambie la función vm.addNote para que guarde nuevas notas en la tabla de datos de notas. Una vez que AMS devuelve que es correcto, el elemento se agrega a la matriz en memoria. Esto evita que la aplicación tenga que volver a cargar la lista completa cada vez que algo se le agrega:

vm.addNote = function () {
  if (vm.addNoteText !== '') {
    Azureservice.insert('notes', {
      "notetext" : vm.addNoteText                 
    }).then(function (newitem) {
      vm.notes.push(newitem);
      vm.addNoteText = '';
    });
  }
}

Por último, cambie la función vm.deleteNote para que elimine la nota de la tabla de notas de AMS. Una vez más, el código espera hasta que AMS es correcto y luego lo elimina de la matriz en memoria:

vm.deleteNote = function (note) {
  Azureservice.del('notes', {
    "id": note.id
  }).then(function () {
    vm.notes.splice(vm.notes.indexOf(note), 1);
  });
}

Ahora todas las notas se recuperan de la tabla de notas en AMS. Cuando un usuario agrega o elimina una nota, esas operaciones tienen lugar en la tabla de datos en AMS. He tenido que escribir muy poco código para lograrlo. Esta es una de las principales ventajas de AMS; es sencillo de configurar y de integrar.

Autenticación de usuarios en Servicios móviles de Azure

La adición de autenticación a una aplicación web puede ser una molestia. Siempre está la cuestión de si se va a desarrollar la suya propia. En la actualidad, a menos que tenga realmente un caso convincente, casi siempre tiene sentido usar uno de los proveedores de identidad principales existentes. Puede tratar los problemas del almacenamiento seguro de las contraseñas y la realización de restablecimientos. AMS facilita la conexión con los proveedores de identidad populares: Microsoft, Facebook, Twitter y Google. AMS integra sin problemas la autenticación y la autorización con la función de inicio de sesión y las tablas creadas en SMS. Para este artículo, he elegido usar una cuenta de Microsoft para autenticación. Una vez configurada la autenticación, cambiaré el ejemplo para que solo los usuarios autenticados puedan ver o editar notas y ver su propia lista.

El primer paso es configurar su aplicación en el portal de Microsoft Live (bit.ly/1JS4jq3). Esto ofrece el id. de cliente y el secreto de cliente que AMS necesita para que funcione Microsoft Identity. Ahora péguelos en la pestaña Identidad de AMS como se muestra en la Figura 7. Hay un excelente artículo que guía a través del proceso de registro de la aplicación en bit.ly/1Ij22hy.

Configuración de Microsoft Identity Provider
Figura 7 Configuración de Microsoft Identity Provider

Luego agregue botones de inicio de sesión y de cierre de sesión a la vista. Agregue el siguiente código de div encima del div que contiene la tabla de notas:

<div class="text-center">
  <button class="btn btn-primary" ng-if="!vm.isLoggedIn()"
  ng-click="vm.login()">Login</button>
  <button class="btn btn-primary" ng-if="vm.isLoggedIn()"
  ng-click="vm.logout()">Logout</button>
</div>

El código ng-if del botón de inicio de sesión hace que el botón de inicio de sesión se muestra solo cuando el usuario no está conectado. El código ng-if del botón de inicio de sesión hace que el botón de inicio de sesión se muestre solo cuando el usuario no está conectado.

Ahora agregue otra etiqueta ng-if al div de contenedor para ocultar la lista y el nuevo cuadro de texto de nota cuando el usuario no ha iniciado sesión. Esta no es una característica de seguridad. AMS aplicará la seguridad. Esto solo hace que el aspecto de la página sea adecuado:

<div class="container" ng-if="vm.isLoggedIn()" style="padding:15px">

Luego agregue las funciones de autenticación al controlador. La vista usa la función isLoggedIn para determinar si debe ocultar o mostrar los botones de inicio/cierre de sesión y ocultar o mostrar la lista de notas. Solo devuelve el resultado de isLoggedIn del módulo Azureservice:

vm.isLoggedIn = function ()
{
  return Azureservice.isLoggedIn();
}

Se llama a la función de inicio de sesión de la aplicación cuando el usuario hace clic en el botón de inicio de sesión. Llama a la función de inicio de sesión en la biblioteca de Azureservice. Mueva el código que consulta SMS para la lista de notas de la parte superior del controlador en esta función. La lista se carga ahora solo después de que el usuario se autentique correctamente:

vm.login = function () {
  Azureservice.login('microsoftaccount')
  .then(function () {
    Azureservice.query('notes', {})
    .then(function (items) {
      vm.notes = items;
    });
  });
}

La función de cierre de sesión cierra la sesión del usuario de AMS llamando a la función de cierre de sesión del módulo Azureservice. También queda en blanco la matriz de notas:

vm.logout = function () {
  vm.notes = [];
  Azureservice.logout();
}

Ahora, lo único que mantiene un usuario no autenticado de la lista de notas es que el código carga la lista solo después de que se autentique el usuario. Esto no es seguro en absoluto. Es mucho mejor que AMS fuerce esto en el back-end. En el Portal de Azure, abra el servicio de AMS y luego abra la tabla de notas y haga clic en Permisos. Cambie todos los permisos a Solo usuarios autenticados como se muestra en la Figura 8. Ahora las llamadas a esta tabla generarán error si el usuario no está autenticado.

Proteger la tabla de Notas
Figura 8 Proteger la tabla de Notas

Separación de los datos de usuario.

Aunque la autenticación del sitio funciona, todos los usuarios siguen compartiendo una sola lista. Vamos a hacer que cada usuario pueda ver y editar solo sus propias notas. Esto requiere únicamente algunos cambios en el Portal de Azure. No cambiaré la aplicación Angular en absoluto.

En primer lugar, vaya a la tabla de datos de notas. Haga clic en las columnas y agregue una nueva columna de cadena denominada userid. Así es cómo asociaré una nota a un usuario. Luego iré a la pestaña de script de la tabla de notas. Seleccione INSERTAR en la lista desplegable de la operación y agregue lo siguiente al script:

function insert(item, user, request) {
  item.userid = user.userId;
  request.execute();
}

Esta nueva línea establece el identificador de usuario de la nueva fila en el userid del proveedor de autenticación. Es mucho más seguro que hacerlo en el código del back-end. El código se ejecuta en Azure; el usuario (o atacante) no tiene acceso a él.

Para filtrar las notas devueltas por id. de usuario, seleccione READ en la lista desplegable de operación y cambie su script:

function read(query, user, request) {
  query.where({ userid: user.userId });
  request.execute();
}

La nueva línea query.where filtra las filas devueltas por la columna userid; se suministra el id. de usuario del usuario que ha iniciado sesión como el valor. El filtrado de los datos en el servidor antes de que llegue al cliente es un método mucho más seguro que intentar hacerlo en el código de cliente.

Ahora la aplicación de notas de Angular almacena notas de forma segura en Servicios móviles de Azure. Cada usuario tiene una lista independiente de las notas a las que solo se puede tener acceso mediante autenticación primero.

Resumen

Con tan solo una pequeña cantidad de código, esta aplicación de demostración está basada ahora en la nube con autenticación y almacenamiento de primera clase. No se deje engañar creyendo que si adopta AngularJS en el front-end, debe abandonar la pila de Microsoft del back-end. AMS se integra perfectamente con AngularJS. Servicios móviles de Azure es un excelente back-end para aplicaciones de AngularJS.


Jonathan Miller es arquitecto experto en CuroGens en Indianapolis. Ha estado desarrollando productos en la pila de Microsoft durante una década y programando en .NET desde sus inicios. Miller es desarrollador de producto de pila completa con experiencia en tecnologías de front-end (Windows Forms, Windows Presentation Foundation, Silverlight, ASP.NET, AngularJS/Bootstrap), software intermedio (servicios de Windows, Web API) y back-ends (SQL Server, Microsoft Azure).

Gracias a los siguientes expertos técnicos de Microsoft por revisar este artículo: David Crawford y Simon Gurevich
Simon Gurevich es un veterano de Microsoft de 15 años de experiencia que actualmente desempeña un cargo de consultor principal de los servicios de consultoría de Microsoft y está especializado en tecnologías de la plataforma de Azure. En el transcurso de su carrera Simon ha estado ofreciendo compromisos de desarrollo y arquitectura de aplicaciones distribuidas en la plataforma de Microsoft y ha trabajado estrechamente con el grupo de productos de Azure en los últimos años. Antes de unirse a Microsoft, Simon tenía un puesto de investigación y desarrollo en un laboratorio de telefonía informática donde estaba desarrollando aplicaciones basadas en servidor que realizaban el enrutamiento de llamadas de telefonía de gran volumen. Simon tiene un Máster en Matemáticas y Ciencias Informáticas.