Contenu principal

Faire fonctionner WP-Cron derrière une authentification http basic

WP-Cron ne marche pas sur votre site ? Voici une raison possible et sa solution.

Cette semaine j’ai été amené à travailler avec CRON, tout du moins la version WordPress, sur mon serveur local pour la première fois.
Pour ceux qui ne savent pas ce qu’est CRON, c’est un système qui permet de programmer des actions, répétitives ou non. Par exemple, les mises à jour automatiques de WordPress utilisent ça, la publication différée d’articles également.
Mon soucis c’est que CRON n’a jamais fonctionné sur mon serveur. Du coup je me suis penché sur le problème.
Il y a deux fichiers qui nous intéressent lorsqu’il s’agit de CRON : wp-includes/cron.php et wp-cron.php. En gros, pour faire court, WordPress utilise le premier pour faire un appel http vers le second (avec wp_remote_post()). Wait, on poste en http… Mon serveur est protégé par une authentification basic… Nom de Zeus, Marty ! Mais c’est bien sûr ! Le problème est donc tout bête, l’appel ne passe pas l’authentification, la solution est donc elle aussi simple, lui donner un login et mot de passe. Ça tombe bien, WordPress dispose d’un filtre au bon endroit :)

Pour ceux qui ne savent pas ce qu’est une authentification basic, il ne s’agit pas de votre page de connexion à WordPress mais d’une authentification avec login et mot de passe pour pénétrer sur le serveur. Si vous ne voyez pas ce que c’est, cet article ne vous sera d’aucune aide.

Pour ceci, je vous suggère de créer une extension Must-Use. On va donc créer un fichier wp-content/mu-plugins/cron-auth.php et lui mettre ceci dedans :

<?php
/**
 * Plugin Name: WP-Cron Auth
 * Description: Make WP-Cron work behind a http auth.
 * Version: 1.0
 * Author: Grégory Viguier
 * Author URI: https://www.screenfeed.fr/greg/
 * License: GPLv3
 * License URI: https://www.screenfeed.fr/gpl-v3.txt
 */

if ( !defined( 'ABSPATH' ) ) {
	die( 'Cheatin\' uh?' );
}

add_filter( 'cron_request', 'sf_cron_request_auth' );

function sf_cron_request_auth($p) {
	if ( strpos( $p['url'], site_url( 'wp-cron.php' ) ) === 0 ) {
		$p['url'] = substr_replace($p['url'], '://MON-LOGIN:MON-MOT-DE-PASSE@', strpos($p['url'], '://'), 3);
	}
	return $p;
}

Je pense que vous aurez deviné qu’il faut remplacer MON-LOGIN par votre login et MON-MOT-DE-PASSE par votre mot de passe (veillez bien à conserver « :// » au début, « : » au milieux et « @ » à la fin).
En somme, on passe le login et le mot de passe dans l’url.

See ya!

PS : Ha, j’oubliais, si vous utilisez un service extérieur pour lancer vos CRONs, il y a ceci plutôt (car mon astuce ne marchera pas de ce cas).
PS2 : Si vous travaillez avec des CRONs, je vous conseille l’extension WP Crontrol qui est simplement indispensable.