web-dev-qa-db-fra.com

Comment implémenter la consommation sécurisée d'OAuth2 en Javascript?

Je suis en train de concevoir une API en PHP qui utilisera OAuth2.0. Mon objectif final est de créer une application frontale en javascript (en utilisant AngularJS) qui accède directement à cette API . Je sais que, traditionnellement, il n'y a aucun moyen de sécuriser les transactions en javascript et qu'il n'est donc pas possible d'accéder directement à une API. Le front-end aurait besoin de communiquer avec le code du serveur qui, à son tour, communiquait directement avec l'API. semble que le flux d'agent utilisateur est conçu pour aider dans cette situation.

J'ai besoin d'aide pour implémenter le flux d'agent utilisateur OAuth2 en javascript (en particulier AngularJS si possible car c'est ce que j'utilise pour mon front-end). Je n'ai pas pu trouver d'exemples ou de tutoriels qui font cela. Je n'ai vraiment aucune idée par où commencer et je ne veux pas lire l'intégralité de la spécification OAuth2 sans au moins voir un exemple de ce que je vais chercher à faire. Ainsi, tous les exemples, tutoriels, liens, etc. seraient grandement appréciés.

45
David Myers

Le flux de subvention implicite (celui que vous appelez le flux d'agent utilisateur ) est exactement la voie à suivre:

L'octroi implicite est un flux de code d'autorisation simplifié optimisé pour les clients implémentés dans un navigateur utilisant un langage de script tel que JavaScript.

Pour comprendre le flux, la documentation de Google pour applications côté client est un très bon point de départ. Notez qu'ils vous recommandent de prendre une étape supplémentaire de validation de jeton pour éviter problèmes d'adjoint confus .

Voici un court exemple d'implémentation du flux utilisant l'API Soundcloud et jQuery, tiré de cette réponse :

<script type="text/javascript" charset="utf-8">
  $(function () {
    var extractToken = function(hash) {
      var match = hash.match(/access_token=([\w-]+)/);
      return !!match && match[1];
    };

    var CLIENT_ID = YOUR_CLIENT_ID;
    var AUTHORIZATION_ENDPOINT = "https://soundcloud.com/connect";
    var RESOURCE_ENDPOINT = "https://api.soundcloud.com/me";

    var token = extractToken(document.location.hash);
    if (token) {
      $('div.authenticated').show();

      $('span.token').text(token);

      $.ajax({
          url: RESOURCE_ENDPOINT
        , beforeSend: function (xhr) {
            xhr.setRequestHeader('Authorization', "OAuth " + token);
            xhr.setRequestHeader('Accept',        "application/json");
          }
        , success: function (response) {
            var container = $('span.user');
            if (response) {
              container.text(response.username);
            } else {
              container.text("An error occurred.");
            }
          }
      });
    } else {
      $('div.authenticate').show();

      var authUrl = AUTHORIZATION_ENDPOINT + 
        "?response_type=token" +
        "&client_id="    + clientId +
        "&redirect_uri=" + window.location;

      $("a.connect").attr("href", authUrl);
    }
  });
</script>
<style>
  .hidden {
    display: none;
  }
</style>

<div class="authenticate hidden">
  <a class="connect" href="">Connect</a>
</div>

<div class="authenticated hidden">
  <p>
    You are using token
    <span class="token">[no token]</span>.
  </p>

  <p>
    Your SoundCloud username is
    <span class="user">[no username]</span>.
  </p>
</div>

Pour envoyer XMLHttpRequests (ce que fait la fonction ajax() dans jQuery) en utilisant AngularJS, reportez-vous à leur documentation du service $http .

Si vous souhaitez conserver l'état, lors de l'envoi de l'utilisateur au point de terminaison d'autorisation, consultez le paramètre state .

50
Jan Gerlinger

Il y a un exemple de Authorization Code Grant approche pour obtenir un jeton du serveur OAuth. J'ai utilisé jQuery ($) pour effectuer certaines opérations.

Tout d'abord, redirigez l'utilisateur vers la page d'autorisation.

var authServerUri = "http://your-aouth2-server.com/authorize",
authParams = {
  response_type: "code",
  client_id: this.model.get("clientId"),
  redirect_uri: this.model.get("redirectUri"),
  scope: this.model.get("scope"),
  state: this.model.get("state")
};

// Redirect to Authorization page.
var replacementUri = authServerUri + "?" + $.param(authParams);
window.location.replace(replacementUri);

Quand on a donné une autorisation pour obtenir un jeton:

var searchQueryString = window.location.search;
if ( searchQueryString.charAt(0) === "?") {
  searchQueryString = searchQueryString.substring(1);
}
var searchParameters = $.deparam.fragment(searchQueryString);

if ( "code" in searchParameters) {
  // TODO: construct a call like in previous step using $.ajax() to get token.
}

Vous pouvez implémenter le Resource Owner Password Credentials Grant de la même manière en utilisant jQuery ou XMLHttpRequest pur et ne faites aucune redirection - car sur chaque redirection vous perdrez l'état de votre application.

Pour moi, j'ai utilisé le stockage local HTML5 pour conserver l'état de mon application pour les données qui ne risquaient pas de menacer la sécurité.

1
Artem Oboturov