2021-01-23
On reprend le développement de notre application visant à afficher des alertes sur nos lives Twitch lorsque des personnes suivent la chaîne, s'abonnent, offrent des bits, etc. Cette application sera, pour rappel, développée sans aucune bibliothèque ni aucun framework, en utilisant uniquement des technologies Web standard : HTML, CSS et JavaScript.
La dernière fois je vous avais expliqué comment déclarer l'application auprès de Twitch et comment l'intégrer à OBS ; aujourd'hui on va voir comment implémenter l'authentification, puisque comme vous le savez certainement, il faut s'authentifier pour accéder aux APIs de Twitch.
--------------------------------------------------------------------------------
📝️ Note:
--------------------------------------------------------------------------------
Cet article fait partie d'une série consacrée à la découverte des APIs Twitch :
Création d'applications et intégration à OBS
Afficher des alertes pour les nouveaux followers !
--------------------------------------------------------------------------------
Twitch propose différentes méthodes d'authentifications, qui répondent à différents besoins et qui fourniront différents types de jetons (tokens).
Twitch permet d'utiliser les 2 méthodes d'authentifications suivant :
Pour nos besoins, OAuth fera parfaitement l'affaire ; c'est donc lui que l'on va utiliser.
Il nous reste maintenant à déterminer par quel workflow d'OAuth on va passer... Et pour savoir cela, commençons par regarder quels types de tokens on peut obtenir et ce qu'ils permettent d'accomplir. Twitch nous permet d'obtenir 2 types de jetons d'authentifications via OAuth :
Dans notre cas, les APIs auxquelles on va vouloir accéder nécessitent un utilisateur authentifié, on va donc avoir besoin d'un user access token.
Maintenant qu'on sait ce que l'on veut, il nous reste à choisir entre l'un des deux workflow suivants qui permettent tous deux d'obtenir le jeton désiré :
Dans notre cas, la méthode d'authentification à utiliser est donc la OAuth Implicite Code Flow.
--------------------------------------------------------------------------------
📝️ Note:
--------------------------------------------------------------------------------
NOTE : J'ai grandement résumé les informations sur OAuth ici, mais si vous souhaitez en apprendre un peu plus, je vous invite à lire cet article de Zeste de Savoir qui me semble une bonne introduction. 👍️
cet article de Zeste de Savoir
--------------------------------------------------------------------------------
Au final le workflow d'authentification va être très simple et se dérouler de la façon suivante :
Schémas du workflow d'autorisation implicite OAuth 2.0
--------------------------------------------------------------------------------
📝️ Note:
--------------------------------------------------------------------------------
NOTE : L'URL sur laquelle on demandera à rediriger l'utilisateur lorsqu'il aura autorisé l'application doit être l'une de celle que l'on avait explicitement autorisée lors de la déclaration de l'application.
--------------------------------------------------------------------------------
Maintenant qu'on sait tout ce que l'on doit savoir à propos de l'authentification, on va mettre ça en pratique. Notre application va se composer de deux fichiers :
Commençons par écrire la page HTML :
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Test application</title> </head> <body> <h1>Test application</h1> <script src="./script.js"></script> </body> </html>
Je pense qu'elle se passe d'explication, elle ne fait rien de plus que d'appeler le script JavaScript que l'on va écrire ensuite... 😄️
Penchons-nous à présent sur le JavaScript. Pour commencer, on va définir quelques constantes dont nous aurons besoin :
const CLIENT_ID = "0123456789abcdefghijklmnopqrstuvwxyz"; const REDIRECT_URI = "http://localhost:8000/"; const SCOPES = [];
que nous avions récupérés dans le précédent article
comme on l'a vu dans l'article précédent
Ensuite, on va écrire quelques helpers, c'est-à-dire des fonctions utilitaires dont on aura besoin dans notre programme :
const helpers = { encodeQueryString: function(params) { // ... }, decodeQueryString: function(string) { // ... }, getUrlParams: function() { // ... }, };
Je ne vous ai volontairement pas mis leur contenu pour l'instant, car ce n'est pas le sujet de cet article, on va donc juste expliquer ce qu'elles font, et pas comment elles le font :
À présent travaillons sur l'authentification elle-même. On va commencer par créer une fonction qui se chargera d'effectuer la redirection sur la page d'authentification avec tous les paramètres nécessaires :
const twitch = { authentication: function() { const params = { client_id: CLIENT_ID, redirect_uri: REDIRECT_URI, response_type: "token", scope: SCOPES.join(" "), }; const queryString = helpers.encodeQueryString(params); const authenticationUrl = `https://id.twitch.tv/oauth2/authorize?${queryString}`; location.href = authenticationUrl; }, };
Il ne nous reste plus qu'à écrire une fonction main() qui sera appelée au chargement de la page et qui appellera notre fonction d'authentification :
function main() { twitch.authentication(); } window.onload = main;
Et là, si on lançait notre page telle quelle, on arriverait bien sur la page d'authentification de Twitch... mais une fois l'autorisation accordée, on serait redirigé en boucle ! En effet, dans notre code on appelle inconditionnellement la fonction d'authentification, sans vérifier si on n'est pas déjà authentifiés...
Pour corriger ça, on va ajouter une fonction qui va vérifier si on est déjà authentifiés ou non :
const twitch = { isAuthenticated: function() { const params = helpers.getUrlParams(); return params["access_token"] !== undefined; }, // ... }
Son fonctionnement est simple : la fonction vérifie que le paramètre access_token est bien présent dans l'URL (ce qui est normalement le cas une fois redirigé depuis la page d'authentification de Twitch).
Il ne nous reste plus qu'à modifier la fonction main() de la manière suivante :
function main() { if (!twitch.isAuthenticated()) { twitch.authentication(); } else { alert("L'utilisateur a bien autorisé l'application !") } }
Voici donc le script au complet, avec autant d'explications que possible :
// ID de l'application récupéré après l'avoir enregistrée const CLIENT_ID = "0123456789abcdefghijklmnopqrstuvwxyz"; // Adresse où l'on veut que l'utilisateur soit redirigé après avoir autorisé // l'application. Cette adresse DOIT être l'une de celles déclarées dans // l'application sur dev.twitch.tv !! const REDIRECT_URI = "http://localhost:8000/"; // Liste des éléments auxquels on souhaite accéder... On reparlera de ça un // peu plus tard ;) const SCOPES = []; // Diverses fonctions utilitaires const helpers = { // Encode un objet sous forme d'une querystring utilisable dans une URL : // {"name": "Truc Muche", "foo": "bar"} -> "name=Truc+Muche&foo=bar" encodeQueryString: function(params) { const queryString = new URLSearchParams(); for (let paramName in params) { queryString.append(paramName, params[paramName]); } return queryString.toString(); }, // Décode une querystring sous la forme d'un objet : // "name=Truc+Muche&foo=bar" -> {"name": "Truc Muche", "foo": "bar"} decodeQueryString: function(string) { const params = {}; const queryString = new URLSearchParams(string); for (let [paramName, value] of queryString) { params[paramName] = value; } return params; }, // Récupère et décode les paramètres de l'URL getUrlParams: function() { return helpers.decodeQueryString(location.hash.slice(1)); }, }; // Fonctions liées à Twitch const twitch = { // Vérifie si l'utilisateur est authentifié ou non isAuthenticated: function() { const params = helpers.getUrlParams(); return params["access_token"] !== undefined; }, // Redirige l'utilisateur sur la page d'authentification de Twitch avec les // bons paramètres authentication: function() { const params = { client_id: CLIENT_ID, redirect_uri: REDIRECT_URI, response_type: "token", scope: SCOPES.join(" "), }; const queryString = helpers.encodeQueryString(params); const authenticationUrl = `https://id.twitch.tv/oauth2/authorize?${queryString}`; location.href = authenticationUrl; }, }; // Fonction principale function main() { // On lance l'authentification si l'utilisateur n'est pas authentifié if (!twitch.isAuthenticated()) { twitch.authentication(); } else { alert("L'utilisateur a bien autorisé l'application !") } } // On appelle la fonction main() lorsque la page a fini de charger window.onload = main;
On a fini d'écrire le code, il reste maintenant à le tester. Pour ce faire il faut qu'on serve notre page à l'aide d'un serveur Web. Vous pouvez utiliser ce que vous voulez ici : Nginx, Apache,...
Pour ma part, je vais servir ma page avec le serveur Web intégré au module http de Python 3 :
python3 -m http.server 8000
Cette commande, si elle est exécutée depuis le dossier contenant mes fichiers index.html et script.js va me permettre d'accéder à mon application à l'adresse http://localhost:8000/ (qui est donc l'adresse de redirection que j'avais explicitement listée lors de la déclaration de l'application).
Si tout se passe bien vous devriez voir une page semblable à celle-ci :
Capture d'écran : authorisation OAuth Twitch
Puis, de retours sur l'application, vous devriez voir le message « L'utilisateur a bien autorisé l'application ! » apparaitre dans une fenêtre d'alerte JavaScript.
Capture d'écran : message affiché en cas de succès
Maintenant, vous avez comment se passe la phase d'authentification auprès des APIs de Twitch, la prochaine fois on va donc pouvoir passer aux choses intéressantes : appeler les APIs Twitch et afficher nos premières notifications !
N'hésitez pas à regarder la vidéo de la session de live coding que j'avais faite sur ce sujet, elle est disponible sur YouTube :
Le code complet de la phase d'authentification est, comme d'habitude disponible sur Github :
N'hésitez pas à poser vos questions en commentaire ou sur Discord, et je vous donne rendez-vous prochainement pour la suite ! 😃️
--------------------------------------------------------------------------------