J’ai déjà fait exactement la même chose. La recommandation d’achamm sur n8n-nodes-azure-openai-ms-oauth2 est la référence la plus propre si tu construis un nœud personnalisé — elle gère l’intégralité du cycle de vie des jetons dans le hook preSend du nœud et ajoute le paramètre du corps de la ressource au moment du rafraîchissement exactement comme tu en as besoin. Le code source est sur npm et GitHub, facile à forker.
Si tu veux un modèle de démarrage encore plus simple à consulter, le nœud Google Drive intégré de n8n a une logique OAuth2 personnalisée dans sa définition de credential qui gère le rafraîchissement des jetons avec des paramètres supplémentaires (c’est dans le dépôt n8n core sous packages/nodes-base/credentials/GoogleOAuth2Api.credentials.ts). Le schéma est pratiquement identique : stocker les jetons, vérifier l’expiration, POSTer vers le point de terminaison des jetons avec les champs de corps supplémentaires dont tu as besoin, mettre à jour le jeton d’accès avant que la vraie requête ne soit envoyée.
Pour ton cas spécifique — serveur OAuth personnalisé, besoin de ressource dans le corps — la logique preSend ressemblerait à quelque chose comme ça (à l’intérieur de la méthode execute ou preSend de ton nœud personnalisé) :
async preSend(request, options) {
const credentials = await this.getCredentials(‘myCustomOAuth2Api’);
// Vérifier si le jeton est expiré
if (Date.now() > credentials.expiresAt) {
const refreshParams = new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: credentials.refreshToken,
client_id: credentials.clientId,
client_secret: credentials.clientSecret,
resource: credentials.resource, // le paramètre de corps crucial
});
const tokenResponse = await this.helpers.httpRequest({
method: 'POST',
url: credentials.accessTokenUrl,
body: refreshParams.toString(),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
});
// Mettre à jour le cache des credentials
credentials.accessToken = tokenResponse.access_token;
credentials.refreshToken = tokenResponse.refresh_token;
credentials.expiresAt = Date.now() + (tokenResponse.expires_in * 1000);
await this.setCredentials('myCustomOAuth2Api', credentials);
}
// Joindre le jeton d’accès à la requête originale
request.headers.Authorization = Bearer ${credentials.accessToken};
return request;
}
C’est essentiellement le plan directeur. Pour la production, tu ajouterais une gestion des erreurs et un stockage des jetons approprié (l’objet credentials de n8n persiste via la base de données automatiquement).
Mais avant que tu écrives une seule ligne de code — essaye d’abord l’astuce du paramètre de requête. Ajoute simplement ?resource=https://your-target à ton accessTokenUrl. Si le serveur l’accepte comme paramètre de requête, c’est réglé en 10 secondes. Beaucoup de serveurs OAuth personnalisés le font, parce qu’ils analysent les deux. Si c’est strict et corps uniquement, alors la route du nœud personnalisé est solide et maintenable à long terme.
Fais-moi savoir quel chemin tu finis par emprunter — je serais ravi de t’aider à déboguer le hook preSend si tu te trouves bloqué.