Ecrit le 15 nov. 2022

Si l'on en croit wikipédia :

OAuth est un protocole libre qui permet d'autoriser un site web, un logiciel ou une application (dite « consommateur ») à utiliser l'API sécurisée d'un autre site web (dit « fournisseur ») pour le compte d'un utilisateur. OAuth n'est pas un protocole d'authentification, mais de « délégation d'autorisation ».

OAuth permet à l'utilisateur de donner, au site ou logiciel « consommateur », l'accès à ses informations personnelles qu'il a stockées sur le site « fournisseur » de service ou de données, ceci tout en protégeant le pseudonyme et le mot de passe des utilisateurs. Par exemple, un site de manipulation de vidéos pourra éditer les vidéos enregistrées sur Dailymotion d'un utilisateur des deux sites, à sa demande.

Le protocole est créé par Blaine Cook et Chris Messina (en) et sa partie principale, OAuth Core 1.0, est finalisée le 3 octobre 2007.

Sources de ce tuto 

Installation du module simple_oauth

composer require drupal/simple_oauth
drush en simple_oauth

Rôle 

Nous verrons plus tard qu'une connexion oauth est liée à un "scope". Ce dernier peut être lui-même lié à un rôle. L'utilisateur aura alors les droits de ses rôles habituels + le rôle lié au scope de oauth.

Clés de cryptage

  • Aller dans Configuration > People > Simple Oauth.
  • Générer les clés publique et privée dans un dossier non publique (ex /www/monsiteweb)
  • Cliquer sur “Generate Key”

Ajouter un "Consumer"

  • Aller dans Configuration > Web services > Consumers et ajouter un nouveau client
  • Ajouter un label (par convention, on utilise le même nom que le rôle créeé précédemment)
  • Ajouter un nouveau “secret” (mot de passe à ne pas perdre car non récupérable)
  • Ajouter le rôle créé dans le scope (Le scope permet que celui qui s’authentifie reçoive les permissions du rôle en plus des autres droits liés à ses rôles)

Exemple de code pour récupérer le token OAuth en javascript via fetch

const payload = new FormData();// cf https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData
payload.append("grant_type", "password");
payload.append("client_id", "9HkwgO9PDLNlH_82uY5Kc_TB9fw-70dg9w9Ex6lJUko");// cf admin/config/services/consumer
payload.append("client_secret", "secret");// cf admin/config/services/consumer
payload.append("username", "bob");// login de l'utilisateur sur drupal
payload.append("password", "bobpwd");// mot de passe de de l'utilisateur sur drupal
payload.append("scope", "oauthscope");// le scope qui correspond à ce "consumer"

function getOAuthToken() {
  fetch('http://mywebsite.fr/oauth/token',{//pensez à modifier par votre nom de domaine
    method: "POST",
    body: payload,//grâce à payload qui est une instance de Formdata, le format du body est bien form-data
  })
  .then(result => result.json())
  .then(token => {
    console.log(`token : `, token);
  })
  .catch(error => {
    console.error("erreur attrapée " + error);
  })
}
getOAuthToken();

Vous constaterez que le token obtenu est en fait une instance d'objet avec les propriétés suivantes :

  • token_type : type du token
  • expire_in : temps avant expiration du token
  • access_token : token servant à demander les ressources
  • refresh_token : token servant à demander un nouveau access_token

Exemple de code pour récupérer les données attachées à un node

En admettant que vous ayez activés les modules "RESTful Web Services" (nom machine rest) et "REST UI" (nom machine restui) puis que vous ayez activé le "endpoint" /node/{node} pour la méthode GET avec pour "provider d'authenfication" "oauth2", voici ce que pourrait donner le code js (en admettant que vous ayez un node/2) :

const payload = new FormData();
payload.append("grant_type", "password");
payload.append("client_id", "9HkwgO9PDLNlH_82uY5Kc_TB9fw-70dg9w9Ex6lJUko");
payload.append("client_secret", "secret");
payload.append("username", "yvan");
payload.append("password", "52Biba95;");
payload.append("scope", "oauth");
/**
 * Récupération de l'objet token
 * @returns promise
 */
function getOAuthToken() {
  return fetch('http://local.d9_3.my/oauth/token', {
    method: "POST",
    body: payload,
  })
    .then(result => result.json())
    .then(token => {
      return token;
    });
}
/**
 * Récupération d'un objet node
 * @param {Object} token 
 * @param {Number} nid 
 * @returns promise
 */
function getNode(token, nid) {
  return fetch(`http://local.d9_3.my/node/${nid}?_format=json`, {
    method: "GET", headers: {
      "Content-type": "application/json; charset=UTF-8",
      "Authorization": token.token_type + " " + token.access_token,
    }
  })
    .then((response) => {
      if (response.status === 200) return response.json(); else throw new Error("Problème de réponse du serveur :  " + response.status);
    })
    .then((data) => {
      console.log("Data  : ", data);
      return data;
    });
}
async function getNode2() {
  try {
    const token = await getOAuthToken()
    const node = await getNode(token, 2);
    console.log(`token : `, token);
    console.log(`node : `, node);
  } catch (error) {
    console.error("Erreur attrapée : ", error)
  }
}
// appel de la fonction asynchrone
getNode2();

 

Si vous n'êtes pas à l'aise avec le js ou avec drupal 9 ou 10 contactez nous pour organiser une formation : contact@coopernet.fr