Obtener el OpenID de WeChat en aplicaciones H5 a menudo puede parecer complicado. Muchos ejemplos en línea dividen funcionalidades en partes separadas, lo cual es estructuralmente razonable, pero para fines de reutilización rápida, reducir dependencias es ventajoso. Basado en experiencia práctica, aquí se presenta un enfoque simplificado y reutilizable.
Requisitos previos
- La cuenta de oficial de WeChat debe estar verificada; de lo contrario, se producirá un error de "Scope" o falta de permisos.
- Configurar un dominio seguro en el penel de administración: acceder a Configuración de la cuenta oficial > Configuración de funciones > Dominio seguro para interfaz JS y Dominio de autorización web.
Implementación del lado del cliente
El código JavaScript maneja la redirección OAuth2 y el intercambio de código por OpenID.
function extractQueryParameter(paramName) {
const regexPattern = new RegExp('[?&]' + paramName + '=([^&;#]+)');
const matchResult = regexPattern.exec(window.location.search);
return matchResult ? decodeURIComponent(matchResult[1].replace(/\+/g, ' ')) : null;
}
function fetchUserOpenId() {
const userAgent = navigator.userAgent.toLowerCase();
if (!/micromessenger/.test(userAgent)) {
return; // Salir si no es WeChat
}
const storedOpenId = sessionStorage.getItem('wxUserOpenId');
if (storedOpenId) {
return; // OpenID ya almacenado
}
const authorizationCode = extractQueryParameter('code');
if (!authorizationCode) {
const currentUrl = window.location.href;
const appId = 'TU_APP_ID_AQUI';
const redirectUri = encodeURIComponent(currentUrl);
const oauthUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_base&state=123#wechat_redirect`;
window.location.href = oauthUrl;
} else {
fetch('/api/exchange-code', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code: authorizationCode })
})
.then(response => response.json())
.then(data => {
if (data.openid) {
sessionStorage.setItem('wxUserOpenId', data.openid);
} else {
window.location.href = '/error';
}
})
.catch(() => {
window.location.href = '/error';
});
}
}
Implementación del lado del servidor
Caso básico: Solo obtener el OpenID
Este endpoint intercambia el código de autorización por un OpenID usando la API de WeChat.
// Ejemplo en PHP
function retrieveOpenId() {
$appId = 'TU_APP_ID';
$appSecret = 'TU_APP_SECRET';
$authCode = $_POST['code'] ?? '';
$apiEndpoint = "https://api.weixin.qq.com/sns/oauth2/access_token";
$queryParams = http_build_query([
'appid' => $appId,
'secret' => $appSecret,
'code' => $authCode,
'grant_type' => 'authorization_code'
]);
$fullUrl = "$apiEndpoint?$queryParams";
$response = file_get_contents($fullUrl);
$responseData = json_decode($response, true);
return json_encode(['status' => 'success', 'data' => ['openid' => $responseData['openid'] ?? null]]);
}
Caso avanzado: Obtener información del usuario
Si se necesita más información del perfil, se debe usar el token de acceso para llamar a la API de userinfo.
// Ejemplo en PHP
function fetchUserProfile() {
$appId = 'TU_APP_ID';
$appSecret = 'TU_APP_SECRET';
$authCode = $_GET['code'] ?? '';
// Paso 1: Obtener token de acceso y OpenID
$tokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?" . http_build_query([
'appid' => $appId,
'secret' => $appSecret,
'code' => $authCode,
'grant_type' => 'authorization_code'
]);
$curlHandle = curl_init($tokenUrl);
curl_setopt_array($curlHandle, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => false
]);
$tokenResponse = curl_exec($curlHandle);
curl_close($curlHandle);
$tokenData = json_decode($tokenResponse, true);
$accessToken = $tokenData['access_token'];
$userOpenId = $tokenData['openid'];
// Paso 2: Obtener datos del usuario
$userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?" . http_build_query([
'access_token' => $accessToken,
'openid' => $userOpenId,
'lang' => 'zh_CN'
]);
$curlHandle = curl_init($userInfoUrl);
curl_setopt_array($curlHandle, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => false
]);
$userInfoResponse = curl_exec($curlHandle);
curl_close($curlHandle);
$userData = json_decode($userInfoResponse, true);
$_SESSION['wechat_user'] = $userData; // Almacenar en sesión
return json_encode($userData);
}