Se connecter avec JWT (JSON Web Token)

Contribuer au projet de part vos connaissances: PHP, HTML, CSS, SQL, JS ....
Répondre
JClini
Gsup LEVEL 0
Messages : 1
Enregistré le : mer. 22 juil. 2026 15:40

Bonjour,

Je vous propose une petite modification qui vous permettra de vous connecter en utilisant un JWT (JSON Web Token)

Mon cas d'usage est avec Nextcloud, ce développement a donc été testé avec cette solution
Si vous voyez des amélioration ou problèmes, notamment de sécurité, n'hésitez pas à me faire des retours


Comment ça marche JWT
Le principe de JWT est qu'un service (ici Nextcloud) va mettre certaines informations non sensible comme une adresse email, un nom d'utilisateur, ... mais donc pas de mot de passe par exemple, dans un JSON (un format standardisé de stockage d'information), et chiffrer ce JSON pour générer un token, une suite de caractères compréhensible qu'après déchiffrement.

Le client (ici GestSup) va recevoir ce token et le déchiffrer pour récupérer les informations qui sont dedans.

Partant du principe que le service qui a généré le token est de confiance, et après des vérifications comme la date d'expiration du token, le client peut alors connecter l'utilisateur lié à ce token, sans lui demander son mot de passe. (C'est l'émetteur du token qui a vérifié que l'utilisateur était bien connecté chez lui)


Le développement
Dans /index.php, à la ligne 225, on ajoute ce code qui va vérifier si un token est donné à GestSup, et si oui, va charger le reste du code nécessaire

Code : Tout sélectionner

//connect with a JSON Web Token
if(isset($_GET['jwt'])) require_once('./jwt.php');
Créer un nouveau fichier nommé jwt.php à la racine du site (dans le même dossier que /index.php), avec le code suivant:

Code : Tout sélectionner

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

/*
Based on Nextcloud token generation
uid == GestSup login

Public key can be found with `occ config:app:get external jwt_token_pubkey_es256`
*/

// Your issuer (Optional, if set up, will be used for more security)
$myIssuer = '';

// Your public key
$myPublicKey = '-----BEGIN PUBLIC KEY-----
Ly6EFN3008RPFxKrBrY706rEJ4qGhd08g7d2Ffq798qF1Txyg+0SG56xd1pqE7UP
796/JPLFr8BYqGyy1Tx7rq8Eq2FFg0d6f7Rge0SGx3+6x5Kdhq10pFdr7==
-----END PUBLIC KEY-----';

// Catch the token
$jwt = $_GET['jwt'] ?? '';

if (!empty($jwt)) {
	try {
    // Decode JWT with the public key
    $key = new Key($myPublicKey, 'ES256');
    $decoded = JWT::decode($jwt, $key);

    // If the token is valid, access to data
		// Note: firebase/php-jwt do the job by checking the validity of the token, including the expiration
    $userData = $decoded->userdata;
    $email = $userData->email;
    $uid = $userData->uid;
    $displayName = $userData->displayName;
    $issuer = $decoded->iss; // Issuer, for nextcloud, it's the default URL of your instance

		// Login
		if ((empty($myIssuer) || $myIssuer === $issuer)) {
			// Search the user with login
			$qry = $db->prepare("SELECT `id` FROM `tusers` WHERE `login`=:login AND `disable`='0'");
			$qry->execute(array('login' => $uid));
			$r=$qry->fetch();
			$qry->closeCursor();

			// If the user exist, log it by adding the user_id in session
			if(!empty($r['id'])) $_SESSION['user_id']=$r['id'];
		}
	} catch (Exception $e) {
    die();
	}
}
Deux modifications sont à apporter dans ce code:
- Vous pouvez ajouter l'information de l'émetteur dans la variable $myIssuer ligne 15. C'est optionnel, si vous le mettez, une vérification sera faite pour rejeter le token si l'émetteur indiqué dans le token n'est pas celui attendu.
- $myPublicKey doit absolument contenir la clé publique de l'émetteur du token, sinon le token ne sera pas déchiffrable (ici la clé est un exemple fictif, remplacez la en entier par la votre)

Aucune dépendance n'est nécessaire car GestSup a déjà Firebase


NextCloud
Comme indiqué en introduction, mon besoin était pour NextCloud. Je vais donc ici indiqué toutes les étapes pour intégrer GestSup dans Nextcloud avec un JWT.

Je vais omettre les problèmes liés à l'embedding de sites présent sur un autre serveur/domaine, pour avec une protection contre ce type d'action. Ce n'est pas bloquant pour la suite car il est toujours posisble de cocher une option pour ouvrir le site dans un nouvel onglet.

Autre prérequis important, dans cette version du code, on part du principe que le login coté Nextcloud et coté GestSup est le même.
Donc si je me connecte sur Nextcloud avec le compte "kevin", je dois me connecter sur GestSup avec le nom de compte "kevin". Le mot de passe lui n'entre pas en compte.
Si vous voulez utiliser l'adresse email à la place, vous devrez modifier la requête lignes 43/44 de jwt.php
Remplacez login et uid par email

- Pour commencer, vous allez avoir besoin d'installer l'app External Site depuis le magasin d'applications de Nextcloud
- Allez ensuite dans les paramètre d'administration et dans le menu External Site
-Ajoutez un nouveau site avec le lien vers votre GestSup
- Ajouter à la fin de l'URL ?jwt={jwt}, ce qui donne par exemple: https://mestickets.fr/index.php.jwt={jwt}
- Récupérez votre clé publique avec la commande "occ config:app:get external jwt_token_pubkey_es256"
Par exemple: sudo -u www-data php /var/www/nextcloud/occ config:app:get external jwt_token_pubkey_es256
Si on part du principe que l'utilisateur qui fait tourner votre Nextcloud est www-data et que votre dossier d'installation est /var/www/nextcloud/
Ces critères sont donc à adapter selon votre cas
- Suivez les étapes plus haut pour ajouter le code dans GestSup et configurer votre clé (Pour NextCloud, l'émetteur est l'URL racine de votre site. Si ça ne fonctionne pas, essayez d'ajouter ou retirer le / à la fin, ou laissez ce paramètre vide)
Répondre