Intégration de l'authentification OAuth2.0 pour les plateformes WeChat en PHP

L'authentification des plateformes WeChat utilise le protocole OAuth 2.0. Le porcessus général comprend les étapes suivantes :

  1. Obtention du code d'autorisation après le consentement de l'utilisateur.
  2. Échange du code d'autorisation contre un access_token.
  3. Récupération des informations utilisateur (nécessite le scope snsapi_userinfo).

Pour plus de détails, consultez la documentation officielle de WeChat : Documentation d'autorisation web WeChat.

Exemple de code PHP

Ce guide propose une implémentation sous forme de classe PHP pour simplifier l'intégration. Le code est divisé en deux fichiers pour une meilleure organisation.

Utilisation générale

Lors de l'appel de la classe UserInfo depuis un autre fichier, assurez-vous de gérer correctement les espaces de noms (namespace).


use app\wechat\UserInfo; // Adaptez le namespace selon votre structure

require_once 'UserInfo.php'; // Assurez-vous que le chemin est correct

$wechatAuth = new UserInfo();
$userData = $wechatAuth->getUserDetails();
print_r($userData);

1. Fichier de configuraton : ConfigTool.php

Ce fichier gère les paramètres de configuration nécessaires pour interagir avec l'API WeChat.


namespace app\wechat;

/**
 * Classe utilitaire pour la configuration des requêtes WeChat.
 */
class ConfigTool {

    /**
     * Retourne un tableau des paramètres de configuration WeChat.
     * @return array Les paramètres de configuration.
     */
    public function getWechatConfig() {
        $config = [];
        
        // Identifiant de l'application WeChat
        $config['appId'] = 'VOTRE_APPID'; 
        
        // Clé secrète de l'application WeChat
        $config['appSecret'] = 'VOTRE_APPSECRET'; 
        
        // URL de redirection après l'autorisation (cette page)
        $config['redirectUri'] = $this->getCurrentUrl();
        
        // URL pour initier le processus d'autorisation et obtenir le code
        $config['authorizeUrl'] = 'https://open.weixin.qq.com/connect/oauth2/authorize';
        
        // URL pour échanger le code contre un access_token et obtenir l'openid
        $config['accessTokenUrl'] = 'https://api.weixin.qq.com/sns/oauth2/access_token';
        
        // URL pour récupérer les informations détaillées de l'utilisateur
        $config['userInfoUrl'] = 'https://api.weixin.qq.com/sns/userinfo';
        
        return $config;
    }

    /**
     * Obtient l'URL complète de la requête actuelle.
     * @return string L'URL complète.
     */
    protected function getCurrentUrl() {
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://";
        return $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    }
}

2. Fichier de gestion des informations utilisateur : UserInfo.php

Cette classe encapsule la logique pour obtenir les inforamtions de l'utilisateur WeChat via OAuth 2.0.


namespace app\wechat;

require_once 'ConfigTool.php'; // Assurez-vous que le chemin est correct

/**
 * Classe pour récupérer les informations des utilisateurs WeChat.
 * 
 * Exemple d'utilisation :
 * $wechatAuth = new UserInfo();
 * $userData = $wechatAuth->getUserDetails();
 */
class UserInfo {

    private $wechatConfig = [];

    /**
     * Constructeur : initialise la configuration WeChat.
     */
    public function __construct() {
        $configTool = new ConfigTool();
        $this->wechatConfig = $configTool->getWechatConfig();
    }

    /**
     * Orchestre le processus d'obtention des détails complets de l'utilisateur.
     * Redirige vers WeChat pour l'autorisation si le code n'est pas présent,
     * sinon, récupère et retourne les informations de l'utilisateur.
     * 
     * @return array|null Les informations de l'utilisateur si disponibles, sinon null.
     */
    public function getUserDetails() {
        // Vérifie si le paramètre 'code' est présent dans l'URL (retour après autorisation)
        if (!isset($_GET['code'])) {
            // Si pas de code, initie le processus d'autorisation
            $this->requestAuthorizationCode($this->wechatConfig['redirectUri']);
            return null; // Arrête l'exécution après redirection
        } else {
            // Si le code est présent, procède à l'obtention du token et des infos utilisateur
            $authorizationCode = $_GET['code'];
            $tokenData = $this->fetchAccessToken($authorizationCode);
            
            if (!empty($tokenData['access_token']) && !empty($tokenData['openid'])) {
                $userInfo = $this->fetchUserInfo($tokenData['access_token'], $tokenData['openid']);
                return $userInfo;
            } else {
                // Gérer l'erreur si l'obtention du token échoue
                $this->handleApiError($tokenData);
                return null;
            }
        }
    }

    /**
     * Redirige l'utilisateur vers la page d'autorisation de WeChat.
     * 
     * @param string $callbackUrl L'URL de redirection après autorisation.
     */
    private function requestAuthorizationCode(string $callbackUrl) {
        $params = [
            'appid' => $this->wechatConfig['appId'],
            'redirect_uri' => urlencode($callbackUrl),
            'response_type' => 'code',
            // 'snsapi_userinfo' permet de récupérer les informations détaillées (pseudo, avatar, etc.)
            // 'snsapi_base' permet seulement d'obtenir l'openid et l'access_token
            'scope' => 'snsapi_userinfo', 
            'state' => md5(uniqid(rand(), true)) // Jeton pour vérifier la requête
        ];
        $url = $this->wechatConfig['authorizeUrl'] . '?' . http_build_query($params) . '#wechat_redirect';
        
        header("Location: {$url}");
        exit;
    }

    /**
     * Échange le code d'autorisation contre un access_token et un openid.
     * 
     * @param string $authCode Le code d'autorisation obtenu.
     * @return array|object Un tableau contenant 'access_token', 'openid', etc., ou un objet d'erreur.
     */
    private function fetchAccessToken(string $authCode) {
        $params = [
            'appid' => $this->wechatConfig['appId'],
            'secret' => $this->wechatConfig['appSecret'],
            'code' => $authCode,
            'grant_type' => 'authorization_code'
        ];
        $url = $this->wechatConfig['accessTokenUrl'] . '?' . http_build_query($params);
        
        $response = $this->curlRequest($url);
        $data = json_decode($response, true); // Décode la réponse JSON en tableau associatif
        
        return $data;
    }

    /**
     * Récupère les informations détaillées de l'utilisateur en utilisant l'access_token et l'openid.
     * 
     * @param string $accessToken L'access_token de l'utilisateur.
     * @param string $openId L'identifiant unique de l'utilisateur WeChat.
     * @return array|null Les informations de l'utilisateur ou null en cas d'erreur.
     */
    private function fetchUserInfo(string $accessToken, string $openId) {
        $params = [
            'access_token' => $accessToken,
            'openid' => $openId,
            'lang' => 'zh_CN' // Langue des informations retournées
        ];
        $url = $this->wechatConfig['userInfoUrl'] . '?' . http_build_query($params);
        
        $response = $this->curlRequest($url);
        $data = json_decode($response, true); // Décode la réponse JSON en tableau associatif
        
        return $data;
    }

    /**
     * Gère les erreurs renvoyées par l'API WeChat.
     * Affiche le code et le message d'erreur.
     * 
     * @param array $errorData Tableau contenant les informations d'erreur ('errcode', 'errmsg').
     */
    private function handleApiError($errorData) {
        if (isset($errorData['errcode']) && isset($errorData['errmsg'])) {
            echo "Erreur API WeChat : Code {$errorData['errcode']} - Message : {$errorData['errmsg']}";
        } else {
            echo "Une erreur inconnue s'est produite.";
        }
        exit;
    }
    
    /**
     * Effectue une requête HTTP GET à l'aide de cURL.
     * 
     * @param string $url L'URL à interroger.
     * @return string|false Le contenu de la réponse ou false en cas d'échec.
     */
    private function curlRequest(string $url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5); // Délai d'attente de 5 secondes
        
        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            // Log l'erreur cURL si nécessaire
            error_log('Erreur cURL : ' . curl_error($ch));
            return false;
        }
        
        curl_close($ch);
        return $response;
    }
}

Il est possible de fusionner ces deux fichiers en une seule classe si vous préférez une structure plus compacte, en fonction des besoins de votre projet.

Étiquettes: PHP WeChat OAuth2.0 Authentification API

Publié le 28 juillet à 09h44