Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

672
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!