Arquitectura, buenas prácticas y desarrollo sobre la nueva herramienta de Microsoft SharePoint 2016

[Office 365] Acceder a la foto de perfil desde una APP

Como os he ido contando en anteriores publicaciones, estamos inmersos en el desarrollo de una APP que más pronto que tarde estará disponible en la Office Store (tengo pendiente un post de como Subir una APP en la Store y no morir en el intento). A lo largo de este desarrollo nos hemos encontrado con algunas limitaciones o aspectos que todavía no están bien definidos dentro de una APP. El primer caso es delñ que vamos a hablar hoy: cómo acceder a la foto de mi perfil desde dentro de una APP. Lo que puede resultar un movimiento relativamente simple resulta algo relativamente complicado dentro de Office 365.

Introducción

Tenemos una APP que solamente tiene una pagina y en la que disponemos de un sitio donde colocar una foto y obtener el nombre del usuario.

  1.  Abrir Visual Studio 2012, crear un proyecto de Aplicación de SharePoint y seleccionamos el tipo de Alojado por SharePoint.
  2. Dentro de la página default.html (que se ha generado al crear el proyecto) añadir las etiquetas html donde va a estar ubicada la imagen. Algo semejante al siguiente código HTML:
    </pre>
    <div id="imagen"></div>
    <div id="nombre"></div>
    <pre>
  3. Del proyecto generado abrir el fichero App.js y añadirle la consulta a la API Social de SharePoint:
    function getProfileUser() {
    $.ajax(
    {
    url:
    appweburl + "/_api/social.feed/my",
    method: "GET",
    headers: { "Accept": "application/json; odata=verbose" },
    success: function (data) {
    successsProfile(data);
    },
    error: function (data) {
    failProfile(data);
    }
    }
    );
    }
    
    function successsProfile(data) {
    var image ;
    if (data.d.Me.ImageUri != null) {
    image = replace(data.d.Me.ImageUri, ' ', '%20');
    }
    var name = data.d.Me.Name;
    $("#imagen").empty();
    $("#nombre").empty();
    $("#imagen").html('  <img class="image" title="" alt="" src=" + image + " />');
    $("#nombre").html(name);
    }
    
    function failProfile(sender, args) {
    alert('Error:' + args.get_message());
    }
    
  4. Dar permisos a nuestra APP para que pueda consultar las caracteristicas sociales para ello hay que ir al manifest.xml de nuestra App e indicarlo. Tal y como esta en la siguiente pantalla:Permisos

Problema

Si ahora lanzamos nuestra APP, que nosotros pensamos que esta perfecta se nos visualiza la siguiente imagen:
Fail Perfil¿Que es lo que esta ocurriendo para que no muestre la imagen?  Se esta produciendo un problema con la autenticación cross-domain de la imagen y debido a esto, SharePoint nos devuelve un error cuando queremos consultar la imagen. Para demostrarlo basta con abrir las herramientas de depuración de vuestro navegador preferido y comprobar que esta ocurriendo cuando se realiza la petición de la imagen:
depuracion navegador

Posibles soluciones

Lo primero que se me ocurre es que al ser una llamada fuera del dominio quizás tengo que utilizar el Proxy que me permite la llamada entre sitios sin problemas con el CrossDomain, tal y como se pone en este ejemplo. ¿Pero realmente estamos intentando acceder a una pagina de otro dominio y que necesitamos autenticación? La respuesta es clara: no, porque los datos nos lo devuelve, estamos intentando acceder a una imagen de la cual tenemos la URL y al estar dentro de SharePoint no debemos de tener problemas de autenticación.
La siguiente idea es mirar a nuestro «amigo» Google y nos encontramos con este post de Wictor Wilen (MVP SharePoint Server) en el que indica que hay un fallo dentro de SharePoint Enterprise y SharePoint Online. Así que sino activas dentro de tu site el Cross-Domain de la Imágenes no se carga la imagen. Su idea es ejecutar este comando PowerShell y de esta forma se soluciona:

asnp Microsoft.SharePoint.PowerShell
$wa = Get-SPWebApplication http://intranet.contoso.com
$wa.CrossDomainPhotosEnabled = $true
$wa.Update()

Pero esta solución a nosotros no nos vale tal cual está. Porque da por supuesto que podemos acceder a ejecutar una consola PowerShell, nosotros tenemos una APP que encima la queremos vender en la Office Store por lo tanto no podemos ir a cada posible cliente potencial que acceda a la administración central y ejecute un script. No es muy elegante que digamos no? 😛

La siguiente acción que se nos ocurre es que la APP mediante el modelo de objetos en cliente realice esta modificación cada vez que se cargue. Ejecutando este código pero transcrito en JavaScript, la APP sigue sin mostrar la imagen. Una APP no es un site de SharePoint, es un espacio aislado y por lo tanto aunque tenga algunas propiedades iguales que un site no se comporta igual.

¿Como lo solucionamos?

Tras probar todas estas opciones prácticamente no me quedaba otra opción que comentarle esta problemática bien al propio soporte de Office 365, bien a los MVP de SharePoint Server con los que tengo buena relación (Juan Carlos Gonzalez y Alberto Diaz) que nos pudieran ayudar a solucionar este problema.

El soporte de Office 365 nos indico que es un bug que estaban viendo los encargados del producto de como poder solucionarlo (mientras tanto hay que buscar otras opciones para que nuestra APP social pueda tener fotos de perfil).

Ahora bien, el bueno de Alberto Diaz me indica que hay un ejemplo en la MSDN en la que para «saltarse» la autenticación lo que hacen es hacer un iframe oculto y desde este iframe realizar la llamada.

En base a esta idea, la solución para pasarlo a nuestro ejemplo estaba clara: crearnos un iframe donde cargamos la imagen y posteriormente realizar la llamada a la API Social y ver si de esta forma ya teniamos la incidencia resuelta. El código queda de la siguiente forma:

function successsProfile(data) {
    var image ;
    if (data.d.Me.ImageUri != null) {
        image = replace(data.d.Me.ImageUri, ' ', '%20');
    }
    var name = data.d.Me.Name;
    var blankiframe;
    var body;
    blankiframe = document.createElement("iframe");
    blankiframe.setAttribute("src", image);
    blankiframe.setAttribute("style", "display: none");
    body = document.getElementsByTagName("body");
    body[0].appendChild(blankiframe);
    window.setTimeout(function()
    {
        $("#imagen").empty();
        $("#nombre").empty();
        $("#imagen").html('  <img class="image" title="" alt="" src=" + image + " />');
        $("#nombre").html(name);
    },2000);
}

Como veis, el código es muy similar al anterior: salvo la diferencia de crear un Iframe y asignarle una imagen. A continuación esperamos 2 segundos (tiempo en el que ya tengamos la imagen cargada) y ejecutamos el mismo código que antes y el resultado sería el siguiente:
Exito

Conclusión

Como ha quedado claro en este ejemplo, no todo es tan fácil como relativamente parece, el mundo de las APP es de reciente creación y Microsoft aun esta mirando los ajustes y las posibles mejoras para adaptarse tanto a los clientes como a los desarrolladores, mientras todo esto llega y hay un producto final terminado nos toca ir tirando de nuestra habilidad con la plataforma y saltando los posibles inconvenientes que nos encontremos por el camino.

Si os interesa, podeis descargar el ejemplo desarrollado en este artículo.

mm

Sobre Adrián Díaz

Adrián Díaz es Ingeniero Informático por la Universidad Politécnica de Valencia. Es MVP de Microsoft en la categoría Office Development desde 2014, MCPD de SharePoint 2010, Microsoft Active Profesional y Microsoft Comunity Contribuitor 2012. Cofundador del grupo de usuarios de SharePoint de Levante LevaPoint. Lleva desarrollando con tecnologías Microsoft más de 10 años y desde hace 3 años está centrado en el desarrollo sobre SharePoint. Actualmente es Software & Cloud Architect Lead en ENCAMINA.
Esta entrada ha sido publicada en APP, buenas practicas, sharepoint 2013 y etiquetada como , , . Enlace permanente .
Suscríbete a Desarrollando sobre SharePoint

Suscríbete a Desarrollando sobre SharePoint

Recibe todas las actualizaciones semanalmente de nuestro blog

You have Successfully Subscribed!

ENCAMINA, piensa en colores