{"id":1581,"date":"2021-10-05T15:28:00","date_gmt":"2021-10-05T14:28:00","guid":{"rendered":"https:\/\/wp.qongzi.dev\/?p=1581"},"modified":"2023-12-21T15:30:29","modified_gmt":"2023-12-21T14:30:29","slug":"tuto-oauth2-0-via-keycloak-pour-une-application-nuxtjs-et-son-api","status":"publish","type":"post","link":"https:\/\/qongzi.com\/tuto-oauth2-0-via-keycloak-pour-une-application-nuxtjs-et-son-api\/","title":{"rendered":"[Tuto] oAuth2.0 via Keycloak pour une application NuxtJS et son API"},"content":{"rendered":"\n

Enjeu<\/h2>\n\n\n\n

Nous avons une application web en interface avec une API. L’objectif est de mettre en place une authentification c\u00f4t\u00e9 application web suivant le workflow oAuth2.0 de type Authorization Code<\/em> tout en restreignant l\u2019acc\u00e8s \u00e0 l’API gr\u00e2ce aux jetons g\u00e9n\u00e9r\u00e9s par le serveur d’authentification.<\/p>\n\n\n\n

Stack<\/h2>\n\n\n\n

L’application web<\/strong> est bas\u00e9e sur le framework NuxtJS<\/a><\/strong> 2<\/strong><\/a>, nous utilisons le module Nuxt\/auth<\/a> <\/strong>dans sa version next pour g\u00e9rer le flow d’authentification.<\/p>\n\n\n\n

L’API est en NodeJS<\/strong> et utilise le framework KoaJS<\/a><\/strong>, le petit fr\u00e8re d’ExpressJS<\/a>. Nous utilisons Typescript pour profiter un maximum des fonctionnalit\u00e9s de l’ORM Prisma<\/a> pour l’interaction avec la base de donn\u00e9es en PostgreSQL<\/a>. Les extraits de code comprendront donc cette couche mais vous pourrez tout \u00e0 fait les r\u00e9utiliser sans Typescript et avec l’ORM\/ODM de votre choix. Vous vous y retrouverez \u00e9galement facilement si votre API est bas\u00e9e sur ExpressJS.<\/p>\n\n\n\n

Le serveur d’authentification est Keycloak<\/a><\/strong>, une solution open source de gestion des diff\u00e9rents workflows de gestion d’acc\u00e8s.<\/p>\n\n\n\n

1. Le workflow<\/h2>\n\n\n\n

1.1. Le standard<\/h3>\n\n\n\n

Nous souhaitons coller au plus proche de la RFC 6749<\/a> et du type de workflow Authorization Code<\/a>. Cette m\u00e9thode garantit de ne pas manipuler de donn\u00e9es critiques au sein de nos applications via l’utilisation d’un code d\u00e9bloquant la g\u00e9n\u00e9ration du token.<\/p>\n\n\n\n

1.2. Notre cas<\/h3>\n\n\n\n

Dans notre cas, il serait tout \u00e0 fait possible de g\u00e9rer le workflow uniquement depuis NuxtJS de fa\u00e7on tr\u00e8s simple gr\u00e2ce au module nuxt\/auth :<\/p>\n\n\n\n

\/\/ nuxt.config.js\r\n\r\nconst KEYCLOAK_BASE_URL = `${VOTRE_HOST_KEYCLOAK}\/auth\/realms\/${VOTRE_REALM_KEYCLOAK}\/protocol\/openid-connect`;\r\n\r\n\r\nexport default {\r\n    \/\/ Votre config nuxt...\r\n    \r\n    modules: [\r\n    \t\/\/ vos modules...,\r\n        '@nuxtjs\/auth-next',\r\n    ],\r\n    \r\n    auth: {\r\n        strategies: {\r\n            keycloak: {\r\n                scheme: 'oauth2', \r\n                endpoints: {\r\n                  authorization: `${KEYCLOACK_BASE_URL}\/auth`,\r\n                  token: `${KEYCLOACK_BASE_URL}\/token`,\r\n                  userInfo: `${KEYCLOACK_BASE_URL}\/auth\/me`,\r\n                  logout: `${KEYCLOACK_BASE_URL}\/logout`,\r\n                },\r\n                token: {\r\n                  property: 'access_token',\r\n                  type: 'Bearer',\r\n                  name: 'Authorization',\r\n                  maxAge: ACCESS_TOKEN_MAX_AGE || 15,\r\n                },\r\n                refreshToken: {\r\n                  property: 'refresh_token',\r\n                  maxAge: REFRESH_TOKEN_MAX_AGE || 60 * 60 * 24 * 30,\r\n                },\r\n                responseType: 'code',\r\n                grantType: 'authorization_code',\r\n                clientId: VOTRE_KEYCLOAK_CLIENT_ID,\r\n                scope: ['openid', 'profile', 'email'],\r\n                codeChallengeMethod: 'S256',\r\n        \t},\r\n\t\t},\r\n  \t},\r\n}\n<\/code><\/pre>\n\n\n\n

\u26a0\ufe0f Pas de panique, nous reviendrons sur les diff\u00e9rentes configurations au gr\u00e9 de l’article !<\/strong><\/p>\n\n\n\n

Toutefois, l’enjeu est de s’authentifier c\u00f4t\u00e9 application web pour contr\u00f4ler l’acc\u00e8s \u00e0 notre API. Pour cela nous avons choisi d’utiliser la librairie openid-client<\/a> qui permet d’interagir depuis le backend avec le serveur d’autorisation (Keycloak).<\/p>\n\n\n\n

Ce besoin ajoute quelques contraintes :<\/p>\n\n\n\n