Sécurité

Accès aux services en ligne avec Windows Runtime et OAuth

Tim Kulp

Télécharger l'exemple de code

Autrefois, à l'époque de Web 1.0, les sites Web étaient des réservoirs de contenu à lire, et rien de plus. Avec l'apparition fracassante de Web 2.0 dans les bureaux de développement, les sites Web sont devenus des services en ligne avec des API utilisées par les développeurs pour combiner à volonté les composants, les données et les fonctionnalités. Aujourd'hui, les applications Web hybrides permettent aux développeurs d'accéder à des bibliothèques de contenus riches sans la surcharge de travail liée à l'hébergement des données dans leur salle de serveurs.

Avec Windows Runtime (WinRT), vous pouvez intégrer la puissance des applications Web hybrides à votre prochaine application du Windows Store. Que vous gériez des données avec XHR (XmlHttpRequest) ou que vous vous authentifiiez auprès d'un service distant avec la classe WebAuthenticationBroker, la bibliothèque Windows pour JavaScript (WinJS) et Windows Runtime facilitent la fusion des services en ligne avec votre application.

Contoso Photo Finish

Dans cet article, je vais concevoir une application Web hybride nommée Contoso Photo Finish. Grâce à elle, les coureurs pourront tenir le compte des kilomètres parcourus et publier une photo de leurs courses. De nombreux coureurs aiment partager sur les réseaux sociaux des informations telles que la distance et le lieu de leur course. Les utilisateurs de Contoso Photo Finish pourront présenter à leurs amis leur course en publiant des commentaires et des photos sur Facebook. Cette application se connectera à deux services différents :

  • Windows SkyDrive pour récupérer une photo de la course
  • Facebook pour publier la photo destinée à leurs amis

Contoso Photo Finish combinera ces services et apportera à son utilisateur une expérience de connexion. Cet article part du principe que Visual Studio 2012 est ouvert et que le modèle JavaScript | Windows Store | Application vide est prêt pour le codage.

Obstacles liés aux applications Web hybrides : l'autorisation et l'authentification

Si une application (Web ou Windows Store) veut publier du contenu sur Facebook, le premier obstacle à franchir est l'authentification. Facebook doit identifier qui se connecte. Lorsque les utilisateurs tentent de se connecter aux applications, ils déclarent une identité (généralement sous la forme d'un nom d'utilisateur) et une information d'identification (par exemple un mot de passe, un jeton de sécurité ou un périphérique biométrique, etc.) pour prouver qu'ils doivent avoir accès à l'identité demandée. L'authentification désigne le processus de validation de l'identité d'un utilisateur grâce à une information d'identification.

Une fois l'utilisateur authentifié, l'application Web hybride a un autre défi à relever : déterminer les actions possibles de l'utilisateur dans le système. L'autorisation désigne le processus d'autorisation et de refus des actions qu'une identité tente d'accomplir en fonction d'un attribut ou d'une appartenance à un rôle de sécurité. À titre d'exemple, dans Twitter, mon identité ne m'autorise pas à supprimer tous les tweets de tous les utilisateurs. Je ne peux pas accomplir cette action, car je ne suis pas membre du rôle de sécurité qui l'autorise. Ensemble, l'authentification et l'autorisation (A&A) se résument par la question : Chers utilisateurs, qui êtes-vous et que pouvez-vous faire ?

Les applications Web hybrides amplifient ces défis, car le développeur qui conçoit l'application Web hybride n'a pas accès à l'emplacement de stockage des identités, des informations d'identification et des rôles de sécurité (souvent désigné sous le terme de « banque d'informations d'identification »). Si je ne peux donc pas identifier les utilisateurs et leurs actions possibles, comment puis-je concevoir une application Web hybride pour des applications comme Facebook ? OAuth apporte la solution !

OAuth : accès aux ressources, pas aux applications

OAuth relève le défi représenté par A&A en matière d'applications Web hybrides. Imaginez qu'une application X veuille accéder au contenu d'un service en ligne Y. Au lieu de s'authentifier auprès de l'application X, l'utilisateur s'authentifie auprès du service en ligne Y, car les informations d'identification de l'utilisateur sont stockées dans la banque d'informations d'identification du service en ligne Y. L'utilisateur autorise alors l'application X à accéder aux ressources spécifiques du service en ligne Y pour une durée limitée. L'autorisation d'accès aux ressources du service en ligne Y est renvoyée à l'application X sous la forme de jeton d'accès (parfois appelé simplement « jeton »).

Dans les modèles A&A traditionnels, deux participants collaborent pour déterminer l'accès d'un utilisateur. l'application et l'utilisateur (ou le serveur et le client). Dans OAuth, un troisième participant est ajouté : le serveur de ressources. Les serveurs de ressources sont des tiers qui ont une ressource (une photo, par exemple) stockée sur le serveur auquel un client doit avoir accès. Dans Contoso Photo Finish, Facebook est un serveur de ressources. L'état de l'utilisateur est la ressource à laquelle Contoso Photo Finish veut accéder pour publier un message.

Clients OAuth et processus d'authentification

Il existe deux types de clients dans OAuth. Le niveau de confiance du client détermine le type à utiliser. Les clients confidentiels peuvent protéger leurs informations d'identification et sont destinés aux environnements très fiables. Les applications Web côté serveur sont des exemples de clients confidentiels. La clé secrète client peut être conservée dans un environnement contrôlé et protégé. Les clients confidentiels utilisent le processus de code d'autorisation pour obtenir un jeton de sécurité en fournissant la clé secrète client au serveur de ressources comme moyen d'authentification du client.

Les clients publics ne peuvent pas protéger leurs informations d'identification, car ils s'exécutent dans un environnement hostile. Les applications utilisateur-agent (autrement dit, les applications Web JavaScript) ou les applications natives (comme les applications du Windows Store) sont des exemples de clients publics. Les clients publics utilisent le processus de « reconnaissance implicite » pour obtenir un jeton de sécurité, car la clé secrète client ne peut pas être stockée de façon sécurisée dans un environnement hostile en dehors du contrôle du développeur.

Vous pouvez configurer les applications du Windows Store pour utiliser les processus de reconnaissance implicite ou de code d'autorisation d'OAuth. Vous trouverez des informations complémentaires sur ces processus à l'adresse bit.ly/yQjyQZ. Il s'agit d'une mesure de sécurité lors de l'utilisation de la reconnaissance implicite chaque fois qu'une application est en dehors du contrôle du développeur.

Dans la figure 1, j'examine un processus de reconnaissance implicite dans lequel un client démarre la conversation en tentant de déterminer l'identité de l'utilisateur avec le serveur de ressources.

Windows Store App Implicit Grant ConversationFigure 1 Conversation de reconnaissance implicite de l'application du Windows Store

Les étapes illustrées dans la figure 1 sont expliquées ci-dessous :

  1. L'application du Windows Store doit exécuter une fonction qui requiert l'accès à l'API Facebook.
  2. L'utilisateur se connecte au serveur de ressources via un URI qui comprend les informations sur l'application du Windows Store tentant d'accéder à l'API Facebook. Il s'agit généralement d'un ID d'application ou d'un code d'identification. L'utilisateur fournit un nom d'utilisateur et un mot de passe pour se connecter à Facebook.
  3. S'il réussi à se connecter, Facebook fournit une application du Windows Store avec un jeton de sécurité.
  4. L'application du Windows Store peut alors fournir à l'utilisateur les données de l'API Facebook à l'aide du jeton de sécurité transmis par Facebook pour obtenir le flux de l'utilisateur, publier des photos, etc.

Grâce à l'espace de noms Windows.Security.Authentication.Web, la réalisation de cette conversation est étonnamment facile.

WebAuthenticationBroker

Dans les applications du Windows Store, la classe WebAuthenticationBroker (bit.ly/RW8czT) est le composant qui communiquera avec le serveur de ressources, fournira les contrôles de connexion et répondra à une connexion réussie, le tout sans avoir besoin de l'application du Windows Store pour savoir quoi que ce soit à propos des informations d'identification de l'utilisateur. Pour l'exemple d'application, Contoso Photo Finish doit publier des photos sur Facebook. Pour cela, l'utilisateur doit s'authentifier auprès de Facebook et recevoir un jeton d'accès.

Ajoutez un nouveau contrôle de page au projet Contoso Photo Finish appelé input.html. Par défaut, Visual Studio fournit beaucoup de balises à votre place. Remplacez « <p>Le contenu s'affiche ici.</p> » dans la section Contenu principal par le bouton suivant :

<input type="button" id="btnAddRun" value="Add Run" />

Il s'agit du bouton sur lequel l'utilisateur clique pour ajouter une course à Photo Finish. À présent, ouvrez input.js et ajoutez la fonction suivante :

function btnAddRun_Click(e) {
  var facebookOauthUrl = "https://www.facebook.com/dialog/oauth";
  var facebookClientId = "[YOUR CLIENT ID]";
  var redirectUrl = "https://www.facebook.com/connect/login_success.html";
  var requestUri = Windows.Foundation.Uri(facebookOauthUrl +
    "?client_id=" + facebookClientId +
    "&redirect_uri=" + encodeURIComponent(redirectUrl) +
    "&response_type=" +
    "token&scope=read_stream,publish_actions&display=popup");
  var callbackUri = Windows.Foundation.Uri(redirectUrl);
  // Web authentication broker will go here
}

Ce code définit les variables qui seront utilisées dans la demande d'authentification. La première variable correspond à l'URL du service OAuth de Facebook. L'ID client est l'identificateur d'application utilisé par Facebook pour identifier Contoso Photo Finish comme l'application avec laquelle l'API Facebook interagira. Un tel identificateur est normalement affecté à une application lorsqu'il est enregistré sur le serveur de ressources. Certains serveurs de ressources appellent les identificateurs les ID client, les ID d'application ou simplement les ID. L'ID à utiliser se trouve dans la documentation des API du serveur de ressources.

Le paramètre redirectUrl détermine l'emplacement de l'application une fois que l'utilisateur a authentifié et approuvé l'accès de l'application aux ressources spécifiées. Dans ce cas, redirectUrl est défini sur un paramètre Facebook standard disponible pour toutes les applications Facebook. Certains services requièrent l'URI de l'application du Windows Store pour être identifiés auprès du serveur de ressources lorsque l'application est enregistrée. L'URI de l'application peut être trouvée à l'aide de la méthode getCurrentApplicationCallbackUri du service Broker pour l'authentification Web. Cette méthode retournera l'URI du contexte local de l'application (commençant par « ms-app:// »). Certains serveurs de ressources ne prennent pas en charge ms-app:// comme un protocole valide pour une redirectUrl. Dans ce cas, vous devrez rechercher une adresse de transfert par défaut similaire à celle fournie par Facebook.

Le callbackUri est ensuite défini. Il s'agit de l'adresse qui informe le service Broker pour l'authentification Web lorsque l'authentification est terminée et renvoie le contrôle à l'application du Windows Store. En réalité, le service Broker ne se rend jamais à cette adresse. Il surveille simplement le serveur de ressources pour demander cette page et retourne ensuite le callbackUri avec une chaîne de requête ou les paramètres de hachage qui ont été ajoutés. Dans ce cas, le paramètre de hachage « access_token » fournira à Contoso Photo Finish le jeton nécessaire pour interagir avec l'API.

La classe WebAuthenticationBroker utilise la méthode authenticateAsync pour se connecter au processus d'authentification avec le serveur de ressources et le terminer. Lorsque la méthode authenticateAsync est appelée, l'application ouvre une fenêtre contextuelle qui affiche l'écran de connexion du serveur de ressources, comme illustré à la figure 2. Une fois l'authentification terminée ou le callbackUri trouvé, la fenêtre contextuelle se ferme.

Resource Server’s Login Pop-up from authenticateAsync
Figure 2 Fenêtre contextuelle de connexion du serveur de ressources à partir de authenticateAsync

Le principal avantage de l'utilisation de cette fenêtre contextuelle est le suivant : l'application du Windows Store n'utilise jamais les informations d'authentification de l'utilisateur pour le gestionnaire de ressources, elle n'a pas non plus besoin de les connaître. Tout ce que l'application connaît, c'est le jeton d'accès retourné par le serveur de ressources. Cette distinction permet de conserver les informations d'identification du serveur de ressources séparées de l'application et d'éviter le risque de sécurité lié au stockage des informations d'identification par l'application. En plus des avantages en termes de sécurité, le développeur n'a rien à coder pour obtenir cette interface. Elle est intégrée à la méthode authenticateAsync. Lorsque le développeur appelle la méthode, l'interface vient avec.

À présent, revenons au code. Remplacez le commentaire « Le service Broker pour l'authentification Web viendra ici. »par le code suivant :

Windows.Security.Authentication.Web.WebAuthenticationBroker.
  authenticateAsync(Windows.Security.Authentication.Web.
  WebAuthenticationOptions.none, requestUri, callbackUri)
.done(
  function (result) {
    // Check the response status here                 
  },
  function (ex) {
    Log(ex);
  }
);

La méthode authenticateAsync accepte les trois paramètres suivants (le troisième étant facultatif) :

  1. WebAuthenticationOptions : il est utilisé pour fournir des instructions au service Broker pour l'authentification Web sur la façon d'afficher la boîte de dialogue d'authentification et sur les données à retourner dans la réponse. Dans l'exemple précédent, l'application utilise « aucune » pour montrer une implémentation commune qui ne passe aucune option au service Broker lors de l'utilisation d'une configuration par défaut.
  2. requestUri : il s'agit du point d'entrée de connexion du serveur de ressources. Dans ce cas, Contoso Photo Finish se connecte au service OAuth de Facebook. Le requestUri doit être établi via une connexion sécurisée en utilisant le protocole HTTPS.
  3. callbackUri : il s'agit de la page qui, lorsque l'utilisateur y accède, renvoie le contrôle au service Broker pour l'authentification Web, comme indiqué précédemment. Cet argument est facultatif, mais si le serveur de ressources ne peut pas (ou ne va pas) rediriger vers ms-app://, ce paramètre définit la façon dont l'application échappera au contrôle du serveur de ressources. Par exemple, dans le code mentionné plus tôt, lorsque https://www.facebook.com/connect/login\_success.html est la page à laquelle l'utilisateur accède après avoir réussi à se connecter, le service Broker pour l'authentification Web prendra le contrôle de l'application à partir du serveur de ressources en fermant la boîte de dialogue d'authentification et en traitant le succès de la promesse. Le callbackUri n'a pas besoin de se trouver directement dans la prochaine page. Il peut se trouver après un Assistant ou tout autre processus qui doit avoir lieu sur le site du serveur de ressources. Cet URI doit normalement être le même que la redirectUrl mais il offre la flexibilité nécessaire à l'extension du processus d'authentification, si nécessaire.

Si le service Broker pour l'authentification Web se connecte au serveur de ressources, la promesse est tenue. La détection du résultat du processus d'authentification a lieu via la propriété ResponseStatus de l'objet WebAuthenticationResult. Dans le code précédent, l'argument de résultat est un objet WebAuthenticationResult avec les trois propriétés suivantes : Response Data (données du serveur de ressources), ResponseErrorDetail (s'il y a eu un problème, lequel ?) et ResponseStatus (quel est l'état de l'authentification ?). Remplacez le commentaire « Vérifier l'état de la réponse ici. » par celui indiqué dans la figure 3.

Figure 3 Utilisation du résultat du processus d'authentification

switch (result.responseStatus) {
  case Windows.Security.Authentication.Web.WebAuthenticationStatus.success:
    var fragment = Windows.Foundation.Uri(result.responseData).fragment;
    if (fragment.indexOf("#access_token=") != -1) {
      var token = fragment.substring(
        new String("#access_token=").length,
        fragment.indexOf("&expires_in="));
      // Add API calls here
    }
    break;
  case Windows.Security.Authentication.Web.WebAuthenticationStatus.userCancel:
    Log(window.toStaticHTML(result.responseData));
    Display("User cancelled the authentication to Facebook.");
    break;
  case Windows.Security.Authentication.Web.WebAuthenticationStatus.errorHttp:
    Log(window.toStaticHTML(result.responseData));
    Display("An error occurred while communicating with Facebook.");
    break;
}

Dans le code de la figure 3, chaque état est vérifié, avec la méthode Log qui enregistre les informations à partir du serveur de ressources et la méthode Display qui indique à l'utilisateur ce qui s'est produit. Pour les messages d'erreur, pensez à afficher des messages conviviaux pour améliorer la convivialité et réduire l'affichage accidentel d'informations sensibles sur un message d'erreur généré par le système. En cas de réussite de l'authentification, le fragment d'URI retourné à partir de Facebook est analysé et stocké dans la variable du jeton à utiliser dans l'appel d'API (pour plus d'informations, reportez-vous à la section « Obtention et publication d'informations via XHR »).                

Lorsque la fonction btnAddRun_Click est terminée, connectez-le à l'objet btnAddRun de la fonction WinJS.UI.Pages.define { ready } :

var btnAddRun = document.getElementById("btnAddRun");
if (null != btnAddRun)
  btnAddRun.addEventListener("click", btnAddRun_Click, false);

À ce stade, l'application dispose d'un jeton d'accès montrant que l'utilisateur est authentifié auprès du serveur de ressources. Dans la dernière section, l'application exécutera les commandes de l'API pour envoyer les données, mais l'application doit d'abord avoir quelque chose à envoyer à Facebook.

Vision d'ensemble

Windows 8 fournit de nombreux contrats qui permettent aux applications de communiquer entre elles, comme les contrats de recherche, de partage et du sélecteur de fichiers, par exemple. Ces contrats peuvent transformer une application en une application Web hybride avec seulement quelques lignes de code. Contoso Photo Finish va profiter de la puissance du contrat du sélecteur de fichiers pour trouver une image de la course de l'utilisateur.

L'une des caractéristiques de mon Windows Phone que j'apprécie le plus est son intégration à SkyDrive. Je peux charger mes photos instantanément pour les stocker sur le cloud. La prochaine fois que je casse mon téléphone (ce qui arrive souvent), mes photos seront donc disponibles en ligne. L'application SkyDrive pour Windows 8 fournit des données au sélecteur de fichiers et rend ainsi la sélection de fichiers à partir de mon compte SkyDrive aussi simple que celle effectuée à partir d'une bibliothèque d'images. La deuxième partie de l'application Web hybride Contoso Photo Finish consommera les données à partir de l'application SkyDrive via le sélecteur de fichiers. Pour ce faire, input.html a besoin de quelques, disons. . . entrées.

Remplacez le bouton btnAddRun avec le code affiché dans la figure 4. Ce code comprend les champs d'entrée pour que l'utilisateur fournisse du contenu à Contoso Photo Finish. Le bouton btnSelectPhoto utilisera le sélecteur de fichiers pour sélectionner le fichier du système à utiliser. Ajoutez une nouvelle fonction à input.js qui sera le gestionnaire de clic de btnSelectPhoto :

function btnSelectPhoto_Click(e) {
  var imgSelectedPhoto = document.getElementById("imgSelectedPhoto");
  var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
  filePicker.fileTypeFilter.replaceAll([".jpg", ".jpeg", ".png"]);
  filePicker.suggestedStartLocation =
    Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
  filePicker.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail;
  // Pick file here
}

Figure 4 Champs d'entrée pour fournir du contenu à l'application

<p>
  <label>Distance</label>
  <input type="number" min="0" max="15" id="txtDistance"
    required /> miles
</p>
<p>
  <label>Comment</label>
  <input type="text" min="0" max="15" id="txtComment" />
</p>
<p>
  <label>Photo</label>
  <input id="btnSelectPhoto" value="Select Photo" type="button" />
  <img src="" id="imgSelectedPhoto" alt="Selected Photo" />
</p>
<p>
  <input type="button" id="btnAddRun" value="Add Run" />
</p>

La fonction commence par la configuration de la variable imgSelectedPhoto, qui sera utilisée pour afficher la photo sélectionnée par l'utilisateur. Ensuite, le code crée un objet du sélecteur de fichiers. L'objet du sélecteur de fichiers permet à Contoso Photo Finish de choisir les fichiers ou les dossiers (dans le cas présent, seulement les fichiers) sur le système ou dans d'autres applications participant au contrat du sélecteur de fichiers pour ouvrir et interagir dans l'application. En utilisant le filtre de type de fichier, le code limite les extensions de fichier accessibles au sélecteur de fichiers. L'application peut uniquement charger des images sur Facebook (par conception). Par conséquent, le fait de limiter le sélecteur de fichiers pour qu'il ne fonctionne qu'avec des types de fichier image spécifiés empêche l'utilisateur de sélectionner des fichiers avec des extensions non valides et non conformes à la fonctionnalité souhaitée. Par ailleurs, comme l'application se concentre sur les images, l'emplacement de démarrage du sélecteur de fichiers est défini sur la bibliothèque d'images. De nombreux emplacements par défaut pourraient être choisis (comme la médiathèque, la bibliothèque de documents, le groupe résidentiel, etc.), mais lorsqu'il s'agit d'utiliser des images, la bibliothèque d'images est l'emplacement de démarrage le plus judicieux. Le dernier paramétrage du sélecteur de fichiers consiste à définir le viewMode sur miniature. Celui-ci affiche un aperçu du fichier et est idéal pour la sélection des images.

Une fois les options définies, il est temps de sélectionner le fichier à utiliser pour la course. Tout d'abord, ajoutez ces deux déclarations de variables directement sous l'instruction « utiliser strictement » :

var selectedPhotoStream = null;
var selectedPhotoFile = null;

Celles-ci maintiendront les valeurs de fichier et de flux pour la fonction btnAddRun_Click lorsque les données sont chargées sur Facebook. Remplacez maintenant le commentaire « Choisir le fichier ici. » par le code affiché dans la figure 5.

Figure 5 Choix d'un fichier

filePicker.pickSingleFileAsync().then(
  function (storageFile) {
    if (storageFile) {
      selectedPhotoFile = storageFile;
      selectedPhotoFile.openAsync(
        Windows.Storage.FileAccessMode.read).then(
        function (stream) {
          selectedPhotoStream = stream;
        document.getElementById("imgSelectedPhoto").src =
          URL.createObjectURL(selectedPhotoFile);
      },
      function (ex) {
        Log(ex);
        Display("An error has occurred while reading the file.");
      });   
     }
    else {
      Display("File was not selected");
    }
  });

La figure 5 affiche beaucoup de code, mais il suffit de retenir trois actions:

  1. Sélectionnez le fichier que l'application utilisera à l'aide du sélecteur de fichiers (pickSingleFileAsync).
  2. Ouvrez le flux de fichier à lire (openAsync).
  3. Stockez le flux et le fichier dans des variables en vue d'une utilisation ultérieure.

Tout le code est standard pour l'utilisation de fichiers et de flux à une exception près : URL.createObjectURL prend un objet et crée une URL pour que l'objet soit affiché via un objet image. La méthode createObjectURL fonctionne avec plusieurs types d'objet, y compris Stream, StorageItem et MediaCapture. En général, elle est utilisée pour afficher du contenu multimédia (images, contenu audio ou vidéo) dans une application du Windows Store. Lors de l'utilisation de createObjectURL, gardez à l'esprit que l'URL doit être supprimée via la méthode URL.revokeObjectURL si vous avez fini de l'utiliser. Cela permettra une utilisation optimale de la mémoire et évitera à l'application du Windows Store de s'y perdre avec trop d'URL temporaires. Pour plus d'informations sur la createObjectURL, consultez la documentation MSDN à l'adresse bit.ly/XdhzOm.

Pour terminer, associez l'événement btnSelectPhoto_Click à l'objet btnSelectPhoto. Ajoutez le code suivant dans la fonction WinJS.UI.Pages.define { ready } :

var btnSelectPhoto = document.getElementById("btnSelectPhoto");
if (null != btnSelectPhoto)
  btnSelectPhoto.addEventListener(
    "click", btnSelectPhoto_Click, false);

À ce stade, Contoso Photo Finish a du contenu à publier et je dispose du mécanisme d'authentification auprès de Facebook pour la publication. Maintenant, l'application doit simplement interagir avec l'API et mettre le contenu en ligne.

Obtention et publication d'informations via XHR

Vous souvenez-vous de l'époque où AJAX était novateur et intéressant ? XHR a fait son entrée dans Internet Explorer 5.5 et a commencé à faire réfléchir les développeurs Web sur la façon dont les applications Web étaient conçues. Au fil du temps, AJAX s'est développé grâce aux nombreuses bibliothèques différentes (comme jQuery) en une solution facile à comprendre et (plus important) facile à implémenter. WinJS.xhr perpétue cette tradition avec une simple API pour obtenir et publier des données sur des services en ligne.

Revenez à la fonction btnAddRun_Click et remplacez le commentaire « Ajouter les appels d'API ici. » par le code affiché à la figure 6.

Figure 6 Génération d'un objet Blob à partir de selectedPhotoStream

var fileBlob = MSApp.createBlobFromRandomAccessStream(
  selectedPhotoFile.contentType,
  selectedPhotoStream);
var message = "I just ran " + document.getElementById(
  "txtDistance").value + " miles with PhotoFinish! " + 
  document.getElementById("txtComment").value;
var data = new FormData();
data.append("source", fileBlob);
data.append("filename", selectedPhotoFile.name);
data.append("access_token", token);
data.append("message", window.toStaticHTML(message));
WinJS.xhr({
  type: "POST",
  url: "https://graph.facebook.com/me/photos",
  data: data,
}).then(
  function (photoid_response) {
    ProcessResponse(photoid_response);
  },
  function (ex) {
    Display("An error occurred while posting the photo.");
    Log(ex);
  });

Auparavant, l'application stockait le StorageFile et le Stream dans les variables selectedPhotoFile et selectedPhotoStream. MSApp.createBlobFromRandomAccessStream prend le selectedPhotoStream et génère un objet Blob (bit.ly/Stfu9z) que l'application passera plus tard au paramètre POST. Cette fonctionnalité est utile pour convertir les objets WinRT en un format qui peut être transféré via HTTP.

Ensuite, le code utilise l'objet FormData (nouveau dans HTML5) pour créer les paramètres qui seront envoyés dans le HTTP POST. FormData est un objet de paires clé/valeur avec une seule méthode : append. À l'aide de la méthode append, les développeurs peuvent créer des champs de formulaire de façon dynamique et les envoyer avec un POST comme si l'événement d'envoi du formulaire était appelé. FormData fournit également les paramètres comme s'ils appartenaient à un formulaire avec un codage multipart/form-data. Cela permet aux développeurs de publier tout type d'entrée (y compris des fichiers) sur le serveur cible.

Dans l'appel à la méthode FormData.append, notez que j'utilise toStatic­HTML (bit.ly/ZRKBka) pour vérifier que le contenu du message est sûr pour l'envoi. L'utilisation de toStaticHTML supprimera les attributs des événements ou le contenu des scripts de la variable du message avant de l'ajouter à l'objet FormData. Alors que j'imagine que Facebook est efficace pour prévenir les attaques de scripts de site à site (entre autres), en tant que développeur d'applications Web hybrides, je souhaite fournir du contenu propre à mes applications. Internet est un vaste endroit, nous devons donc tous nous surveiller les uns les autres.

Le reste du bloc de code est l'appel WinJS.xhr. Cette fois-ci, le code utilise quelques attributs supplémentaires de XHR, y compris :

  • type : il définit la méthode HTTP à utiliser. Par défaut, le type est défini sur GET. Ce code utilise POST, car l'application envoie du contenu à l'API Facebook.
  • data : il est constitué des paramètres à passer avec le POST.

Lorsque la promesse est retournée par la méthode success, Contoso Photo Finish traite l'ID de la photo en vue d'une récupération ultérieure. En cas d'erreur, le message d'erreur standard s'affiche et l'exception est consignée.

WinJS.xhr est semblable à d'autres wrappers XHR. Si vous connaissez bien les bibliothèques JavaScript telles que jQuery, vous pourrez apprendre WinJS.xhr facilement. Vous pouvez rencontrer le piège suivant : contrairement à XHR, il n'existe pas d'option de délai d'expiration sur la méthode WinJS.xhr. La définition d'un délai d'expiration s'effectue en encapsulant l'appel WinJS.xhr avec la méthode WinJS.Promise.timeout (bit.ly/Qgtx7a). En ajoutant le code suivant au début de l'appel WinJS.xhr, je définis un délai d'expiration de 10 secondes pour le POST :

WinJS.Promise.timeout(1000, WinJS.xhr({ ... });

Si la promesse WinJS.xhr n'est pas effectuée dans les 10 secondes, elle expirera et sera traitée par la fonction d'erreur de la promesse du délai d'expiration.

Premières étapes de la fusion de votre application

Dans cet article, j'ai examiné l'authentification, l'obtention de fichiers et l'envoi de données avec WinJS et Windows Runtime. Ces compétences de base peuvent vous servir à concevoir des applications du Windows Store qui sont limitées uniquement par votre imagination et vos clés de développeur. Utilisez le contenu de cet article et explorez votre service en ligne préféré. Grâce à WinJS.xhr, votre application du Windows Store peut interagir avec les innombrables API disponibles en ligne. Grâce au service Broker pour l'authentification Web, votre application peut connecter les utilisateurs avec leurs personnalités, contenu et communautés en ligne à l'aide d'OAuth ou OpenID. WinJS et Windows Runtime vous apportent tous les outils nécessaires pour concevoir une application dont la valeur est supérieure à la somme de tous les services en ligne.

Tim Kulp dirige l'équipe de développement chez FrontierMEDEX à Baltimore. Vous pouvez le retrouver sur son blog seccode.blogspot.com ou sur Twitter à l'adresse Twitter.com/seccode, où il parle du code, de la sécurité et de la scène gastronomique de Baltimore.

Merci aux experts techniques suivants d'avoir relu cet article : Sunil Gottumukkala et Jeremy Viegas