tiene problemas para mostrar una imagen cargada en Amazon s3 por fine-uploader

Ahora estoy intentando configurar fineuploader-s3 para mostrar una imagen del archivo cargado correctamente en el servidor aws, como se hizo en la página de ejemplo aquí: http://fineuploader.com/#s3-demo

Estoy (todavía) usando el código en https://github.com/Widen/fine-uploader-server/blob/master/php/s3/s3demo.php , y he agregado

uploadSuccess: { endpoint: "s3demo.php?success" } 

a la instancia de fine-uploader en mi archivo javascript, de modo que el enlace temporal debe ser generado por la función en el archivo s3demo.php.

Me di cuenta de que tenía que instalar AWS SDK para que funcionara. El método zip de instalación realmente no funcionaba, así que estoy usando phar. Cambié esa sección del archivo s3demo.php a:

 require 'aws.phar'; use Aws\S3\S3Client; 

También comenté estas dos líneas:

 $serverPublicKey = $_SERVER['PARAM1']; $serverPrivateKey = $_SERVER['PARAM2']; 

Tengo dos problemas para hacer que esto funcione. El primero es que algo está saliendo mal con mi respuesta exitosa de AWS, de la cual creo que se supone que debo obtener el enlace al archivo.

El archivo se carga perfectamente, pero aparece un error en la consola:

 [FineUploader 3.8.0] Sending POST request for 0 s3.jquery.fineuploader-3.8.0.js:164 [FineUploader 3.8.0] Received the following response body to an AWS upload success request for id 0: 
Fatal error: Uncaught exception 'Guzzle\Http\Exception\CurlException' with message '[curl] 28: Connection timed out after 1001 milliseconds [url] http://169.254.169.254/latest/meta-data/iam/security-credentials/' in phar:///MYSITE/aws.phar/Guzzle/Http/Curl/CurlMulti.php:339 Stack trace: #0 phar:///MYSITE//aws.phar/Guzzle/Http/Curl/CurlMulti.php(280): Guzzle\Http\Curl\CurlMulti->isCurlException(Object(Guzzle\Http\Message\Request), Object(Guzzle\Http\Curl\CurlHandle), Array) #1 phar:///MYSITE//aws.phar/Guzzle/Http/Curl/CurlMulti.php(245): Guzzle\Http\Curl\CurlMulti->processResponse(Object(Guzzle\Http\Message\Request), Object(Guzzle\Http\Curl\CurlHandle), Array) #2 phar:///MYSITE//aws.phar/Guzzle/Http/Curl/CurlMulti.php(228): Guzzle\Http\Curl\CurlMulti->processMessages() #3 phar:///MYSITE//aws.phar/Guzzle/Http/Curl/CurlMulti.php(212): Guzzle\Http\Curl\CurlMulti->executeHandles() #4 phar:///MYSITE/z/aw in phar:///home/nextq2/public_html/lenz/aws.phar/Aws/Common/InstanceMetadata/InstanceMetadataClient.php on line 82
s3.jquery.fineuploader-3.8.0.js:164 [FineUploader 3.8.0] Upload success was acknowledged by the server. s3.jquery.fineuploader-3.8.0.js:164

¿Esto significa que hay algún problema con la instalación de AWS SDK o con la configuración de mis permisos en Amazon? Para las configuraciones CORS e IAM? Que siguen siendo los siguientes:

  MY WEBSITE POST 3000 *  

La política de mi grupo en IAM:

  { "Version":"2012-10-17", "Statement":[{ "Effect":"Allow", "Action":"s3:PutObject", "Resource":"arn:aws:s3:::MY_BUCKET/*” }] } 

El segundo problema, que estoy seguro de que debería poder descifrar pero no puedo, es cómo acceder a la matriz json generada por s3demo.php en mi javascript para poder mostrar la imagen cargada. Supongo que no es $ templink [0]. Me preguntaba si sería posible ver el código de ejemplo que da al botón de vista en http://fineuploader.com/#s3-demo su función. Si debería hacer una segunda pregunta aquí, me complace hacerlo.

Muchas gracias por tu tiempo.

EDITAR para agregar mi código completo según lo solicitado:

PHP:

  $serverPublicKey, 'secret' => $serverPrivateKey )); } // Only needed if the delete file feature is enabled function deleteObject() { getS3Client()->deleteObject(array( 'Bucket' => $_POST['bucket'], 'Key' => $_POST['key'] )); } function signRequest() { header('Content-Type: application/json'); $responseBody = file_get_contents('php://input'); $contentAsObject = json_decode($responseBody, true); $jsonContent = json_encode($contentAsObject); $headersStr = $contentAsObject["headers"]; if ($headersStr) { signRestRequest($headersStr); } else { signPolicy($jsonContent); } } function signRestRequest($headersStr) { if (isValidRestRequest($headersStr)) { $response = array('signature' => sign($headersStr)); echo json_encode($response); } else { echo json_encode(array("invalid" => true)); } } function isValidRestRequest($headersStr) { global $expectedBucket; $pattern = "/\/$expectedBucket\/.+$/"; preg_match($pattern, $headersStr, $matches); return count($matches) > 0; } function signPolicy($policyStr) { $policyObj = json_decode($policyStr, true); if (isPolicyValid($policyObj)) { $encodedPolicy = base64_encode($policyStr); $response = array('policy' => $encodedPolicy, 'signature' => sign($encodedPolicy)); echo json_encode($response); } else { echo json_encode(array("invalid" => true)); } } function isPolicyValid($policy) { global $expectedMaxSize, $expectedBucket; $conditions = $policy["conditions"]; $bucket = null; $parsedMaxSize = null; for ($i = 0; $i  $expectedMaxSize) { // You can safely uncomment this next line if you are not depending on CORS //header("HTTP/1.0 500 Internal Server Error"); deleteObject(); echo json_encode(array("error" => "File is too big!")); } else { echo json_encode(array("tempLink" => getTempLink($bucket, $key))); } } function testfunction(){ alert('whatever'); } // Provide a time-bombed public link to the file. function getTempLink($bucket, $key) { $client = getS3Client(); $url = "{$bucket}/{$key}"; $request = $client->get($url); return $client->createPresignedUrl($request, '+15 minutes'); } function getObjectSize($bucket, $key) { $objInfo = getS3Client()->headObject(array( 'Bucket' => $bucket, 'Key' => $key )); return $objInfo['ContentLength']; } ?> 

Mi html Usé otro ejemplo que Mark tenía en StackOverflow para esta prueba, porque eventualmente quiero enviar otros datos simultáneamente:

    test of <a href="https://www.rephp.com/php/fine-uploader" title="Topics of fine uploader" target="_blank">fine uploader</a>     .button { display: block; height: 30px; width: 100px; border: 1px solid #000; }        view image 
click here

Mi javascript:

 $(document).ready(function() { $("#triggerUpload").click(function () { $("#manual-fine-uploader").fineUploaderS3('uploadStoredFiles'); }); function submitForm () { if ($(this).fineUploader('getInProgress') == 0) { var failedUploads = $(this).fineUploaderS3('getUploads', { status: qq.status.UPLOAD_FAILED }); if (failedUploads.length == 0) { // do any other form processing here $("#uploader").submit(); } } }; $("#manual-fine-uploader").fineUploaderS3({ autoUpload: false, debug: true, request: { endpoint: "http://my bucket name.s3.amazonaws.com", accessKey: “I put my access key here” }, validation: { allowedExtensions: ['jpeg', 'jpg', 'gif', 'png'], sizeLimit: 15000000, itemLimit: 3 }, signature: { endpoint: "s3demo.php" }, camera: { ios: true }, iframeSupport: { localBlankPagePath: "/success.html" }, uploadSuccess: { endpoint: "s3demo.php?success" } }); }); 

Parece que simplemente quiere reflejar el comportamiento de la demostración de S3 en FineUploader.com. Entonces, la pieza con la que aparentemente tiene problemas es la parte de la demostración que le permite ver / descargar el archivo que ha subido. Supongo que no está configurando las variables de entorno PARAM1 y PARAM2 . Deberías echarle un vistazo a cómo funciona el súper global $_SERVER en la documentación de PHP. Este código, tal como está, espera que tenga una variable de entorno del sistema llamada PARAM1 que contiene la clave pública de AWS asociada con el usuario de IAM que debería haber creado para su servidor (no su cliente). La variable de entorno del sistema PARAM2 debe establecerse en la clave secreta para este mismo usuario. Puede establecer estas variables de entorno o establecer los $serverPrivateKey globales PHP de $serverPublicKey y $serverPrivateKey en las claves públicas y secretas del usuario IAM del lado del servidor, respectivamente.

Tenga en cuenta que la elección deficiente del nombre para las variables de entorno del sistema asociadas con la clave pública y secreta de AWS del servidor ( PARAM1 y PARAM2 ) se debe al hecho de que el servidor de la demostración fineuploader.com S3 se ejecuta en una instancia de AWS EC2 creada por Amazon Servicio Elastic Beanstalk . Elastic Beanstalk no proporciona (al menos no proporciona obviamente) una forma de nombrar variables de entorno del sistema a través de la interfaz de usuario Elastic Beanstalk para aplicaciones PHP. Los nombra PARAM1 , PARAM2 , etc.

Las $serverPublicKey y $serverPrivateKey NO deben ser las mismas claves asociadas con el usuario de IAM que usted creó para las tareas del lado del cliente. Debería haber creado un usuario de IAM diferente con los permisos adecuados para las tareas del lado del servidor. Por ejemplo, si desea admitir la función de eliminar archivo, le conviene tener un usuario de IAM con el permiso “S3: DeleteObject”. Este usuario debe estar restringido a las tareas del lado del servidor solo por razones de seguridad.

En su caso, su usuario de IAM del lado del servidor debe tener el permiso “S3: GetObject” en su depósito. Este permiso es requerido para poder obtener objetos de tu cubo. El enfoque más seguro es solo otorgar este permiso a su usuario de IAM del lado del servidor. Probablemente esté preguntando: “Si mi usuario del lado del cliente no puede leer el objeto de mi depósito, ¿cómo puedo permitir que el archivo se descargue del lado del cliente?” Bueno, una opción es establecer la opción acl en Fine Uploader para “lectura pública” y luego construir una URL del lado del cliente usando esta convención: ” http://mybucket.s3.amazonaws.com/objectkey “. Esta NO es la forma en que funciona la demostración de S3 en fineuploader.com. Sigue leyendo para más detalles …

No quería darles a los usuarios acceso ilimitado a los archivos que cargaron en el depósito S3 de Fine Uploader, así que dejé el acl en “privado” (el valor predeterminado), solo le di permiso a mi usuario IAM del lado del servidor “S3: GetObject” al cubo de Fine Uploader S3, y hago que el servidor devuelva una URL con signo “bombardeado con el tiempo” para el objeto asociado en el depósito. La URL devuelta por el servidor contiene un parámetro de caducidad que solo permite su uso durante 15 minutos. Cualquier bash de cambiar ese parámetro de expiración en la cadena de consulta invalidará la firma y la solicitud fallará. La función getTempLink en el ejemplo de PHP generará una URL con signo de bombardeo de tiempo que se devuelve en la respuesta a la uploadSucess.endpoint de uploadSucess.endpoint POST de Fine Uploader. Puede acceder a este valor contribuyendo con un controlador de eventos complete . El parámetro de objeto responseJSON pasado a su callback contendrá una propiedad tempLink que contendrá la URL firmada. A continuación, puede generar un ancla con el atributo src establecido en el valor de esta propiedad.