Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

664
Vistas
¿Cómo verificar el punto final de discordia usando php?

Tengo algunos problemas para crear un bot de Discord. Quiero que pueda responder a los comandos de barra, pero para hacerlo necesito verificar un punto final. Estoy usando PHP 7.4 y no puedo usar bibliotecas externas (alojamiento en un servidor que no las permite). He encontrado documentos para PHP, pero requieren bibliotecas para funcionar. Intenté tomar los documentos de Node.JS y "convertirlos" a PHP. Aquí está mi código:

 <?php $public_key = "shh-it's-a-seekrit"; $headers = getallheaders(); $signature = $headers["X-Signature-Ed25519"]; $timestamp = $headers["X-Signature-Timestamp"]; $raw_body = file_get_contents('php://input'); /* To compute the signature, we need the following * 1. Message ($timestamp + $body) * 2. $signature * 3. $public_key * The algorythm is SHA-512 */ $message = $timestamp . $raw_body; $hash_signature = hash_hmac('sha512', $message, $public_key); if (!hash_equals($signature, $hash_signature)) { header("HTTP/1.1 401 Unauthorized", true, 401); die("Request is not properly authorized!"); } $return_array = [ 'type' => 1, ]; echo json_encode($return_array); ?>

Cuando pongo la dirección en la que se sube el archivo y trato de guardar los cambios, Discord dice lo siguiente:

Errores de validación: interacciones_punto_final_url: no se pudo verificar la URL del punto final de interacciones especificada.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Este es un método que me funciona en PHP 8.1.

Pase los encabezados y el cuerpo JSON sin procesar, y devuelve una matriz con el código de respuesta y la carga útil para enviar de vuelta a través de lo que esté usando para manejar la respuesta. Tenga en cuenta que la respuesta debe estar codificada en JSON.

$discord_public es la clave pública de la aplicación Discord.

 public function authorize(array $headers, string $body, string $discord_public): array { $res = [ 'code' => 200, 'payload' => [] ]; if (!isset($headers['x-signature-ed25519']) || !isset($headers['x-signature-timestamp'])) { $res['code'] = 401; return $res; } $signature = $headers['x-signature-ed25519']; $timestamp = $headers['x-signature-timestamp']; if (!trim($signature, '0..9A..Fa..f') == '') { $res['code'] = 401; return $res; } $message = $timestamp . $body; $binary_signature = sodium_hex2bin($signature); $binary_key = sodium_hex2bin($discord_public); if (!sodium_crypto_sign_verify_detached($binary_signature, $message, $binary_key)) { $res['code'] = 401; return $res; } $payload = json_decode($body, true); switch ($payload['type']) { case 1: $res['payload']['type'] = 1; break; case 2: $res['payload']['type'] = 2; break; default: $res['code'] = 400; return $res; } return $res; }
over 4 years ago · Santiago Trujillo Denunciar

0

Para completar, agregue el código faltante a la respuesta de @Coder1:

 <?php $payload = file_get_contents('php://input'); $result = endpointVerify($_SERVER, $payload, 'discord app public key'); http_response_code($result['code']); echo json_encode($result['payload']); function endpointVerify(array $headers, string $payload, string $publicKey): array { if ( !isset($headers['HTTP_X_SIGNATURE_ED25519']) || !isset($headers['HTTP_X_SIGNATURE_TIMESTAMP']) ) return ['code' => 401, 'payload' => null]; $signature = $headers['HTTP_X_SIGNATURE_ED25519']; $timestamp = $headers['HTTP_X_SIGNATURE_TIMESTAMP']; if (!trim($signature, '0..9A..Fa..f') == '') return ['code' => 401, 'payload' => null]; $message = $timestamp . $payload; $binarySignature = sodium_hex2bin($signature); $binaryKey = sodium_hex2bin($publicKey); if (!sodium_crypto_sign_verify_detached($binarySignature, $message, $binaryKey)) return ['code' => 401, 'payload' => null]; $payload = json_decode($payload, true); switch ($payload['type']) { case 1: return ['code' => 200, 'payload' => ['type' => 1]]; case 2: return ['code' => 200, 'payload' => ['type' => 2]]; default: return ['code' => 400, 'payload' => null]; } }
over 4 years ago · Santiago Trujillo Denunciar

0

De acuerdo con la documentación de Discord , el punto final de las interacciones debe hacer dos cosas:

  • Su punto final debe estar preparado para ACK un mensaje PING
  • Su punto final debe estar configurado para manejar correctamente los encabezados de firma; más sobre eso en Seguridad y autorización

La primera parte es muy sencilla:

Entonces, para ACK correctamente la carga útil, devuelva una respuesta 200 con una carga útil de tipo: 1:

Por lo tanto, debe devolver un objeto JSON y no una matriz (tal vez ese sea uno de los problemas con su código).

Además, el punto final debe poder responder a solicitudes no válidas como:

También realizaremos comprobaciones de seguridad rutinarias y automatizadas en su terminal, incluido el envío intencionado de firmas no válidas. Si no pasa la validación, eliminaremos la URL de sus interacciones en el futuro y le avisaremos por correo electrónico y mensaje directo del sistema.

¡Una cosa que noté es que Discord envía sus encabezados en minúsculas! Otro problema es que usas:

$raw_body = file_get_contents('php://input'); eso no se ve bien.

Finalmente, si conoce node.JS, eche un vistazo a mi ejemplo de trabajo: https://github.com/iaforek/discord-interactions

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda