Cómo hacer que la URL de carga de almacenamiento en la nube de Google funcione solo una vez con HTTP PUT y caduque en un tiempo determinado

Roshan Upreti

Estoy usando los siguientes dos JAVAmétodos para crear un archivo firmado URLpara cargarlo en Google Cloud Storage, usando HTTP PUT. Se supone que el primer método genera la URL de carga real usando POST, mientras que el segundo se supone que genera el URLuso serviceAccountCredentials, que será usado (para POST) por el primero.

Primer método

 public String getUploadLink(String bucketName, String uuid, String objectName, String mimeType)
        throws IOException, GenericAttachmentException {
    if (!bucketExists(bucketName)) {
        createBucket(bucketName);
    }
    URL myURL = new URL(getSignedUrlToPost(bucketName, uuid, objectName, mimeType));
    HttpURLConnection myURLConnection = (HttpURLConnection) myURL.openConnection();
    myURLConnection.setRequestMethod("POST");
    myURLConnection.setRequestProperty("Content-Type", mimeType);
    myURLConnection.setRequestProperty("x-goog-resumable", "start");
    // Send POST request
    myURLConnection.setDoOutput(true);
    DataOutputStream wr = new DataOutputStream(myURLConnection.getOutputStream());
    wr.flush();
    wr.close();
    int responseCode = myURLConnection.getResponseCode();
    if (responseCode != 201) {
        throw new GenericAttachmentException(500,
                "Error generating signed URL",
                "Something went wrong while attempting to generate the URL.");
    }
    return myURLConnection.getHeaderField("Location");
}

Segundo método

private String getSignedUrlToPost(String bucketName, String uuid, String objectName,
                                  String mimeType) throws GenericAttachmentException {
    try {
        String verb = "POST";
        long now = System.currentTimeMillis();
        /* Expire in a minute. */
        long expiryTimeInSeconds = (now + 60 * 1000L) / 1000;
        String canonicalizedExtensionHeaders = "x-goog-resumable:start";
        byte[] sr = serviceAccountCredentials.sign(
                (verb + "\n\n" + mimeType + "\n" + expiryTimeInSeconds + "\n" + canonicalizedExtensionHeaders
                        +
                        "\n" + "/" + bucketName + "/" + uuid + "/" + objectName).getBytes());
        String urlSignature = new String(Base64.encodeBase64(sr));
        return "https://storage.googleapis.com/" + bucketName + "/" + uuid + "/" + objectName +
                "?GoogleAccessId=" + serviceAccountEmail +
                "&Expires=" + expiryTimeInSeconds +
                "&Signature=" + URLEncoder.encode(urlSignature, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        throw new GenericAttachmentException(500,
                "Something went wrong while encoding the URL.",
                e.getMessage());
    }
}

Esto me da una carga URL, de la siguiente manera:

https://storage.googleapis.com/bucket-name/7c9a5bd6-ece2-497d-b485-a9c53e27f253/a.pdf?GoogleAccessId=storage-dev@project-name-xxxxxx.iam.gserviceaccount.com&Expires=1592883655&Signature=IlTGvwGNN8VYrPE9qzSW0AIAwqMvbNoZ34TQ4nr4Po5vwZx78or9iiqBhO0jqoeoX6BYP%2BHGkWPIKMUijB%2FZ0L6Z%2BtnaZZkIJ581YQ3JK8BEHWqWyf0V07RwAN0TGAyld7h1JntWmGDyXKtjmy6Skt1C0GocJZA2x9GMxo94OD9kpFbjBucixgQDE%2BEtCzDUXWkymATls690pyLftXhAI0CVWg%2FPlcAe2Q%2F9M%2F68s5eWVSXa0%2BXIVQQ%2FucgXO8RbEDeu%2BWjrL3TcYQFTFd8Q%2BvcwKkpjbmKGpmMnYuTc7HSKrRWLLGxixsLBSjKdQDK4Tu14%2F0ROJVJo4Gv%2FX4oknQ%3D%3D&upload_id=AAANsUlwcmdpeCuME5YbeSpnfw5eQw_Sb65xl7t59b6GcNkNE0PUfe44tUDXHfobXRo-EBGI6X-I5zPqXyPBm4paSyBGyzZCWw

Cuestiones:

  1. Puedo cargar un objeto, usando lo anterior URL, pero el enlace no caduca después de un minuto.
  2. El enlace no se invalida después de que se realiza la carga inicial, es decir, cuando uso el mismo enlace para cargar, por ejemplo, xyz.jpgusar HTTP PUT, regresa 200 OK, aunque en realidad no carga xyz.jpgni reemplaza el archivo original.

¿No debería invalidarse el enlace de carga una vez que se usa para cargar algo en el servidor? ¿Me estoy perdiendo de algo? Realmente le vendría bien un poco de ayuda.

Rafael Lemos

Las bibliotecas de Google Cloud para crear una URL firmada son en realidad mucho más simples que crearla "manualmente", como puede ver en el ejemplo de código de muestra en esta documentación oficial . Después de eso, su getSignedUrlToPostfunción podría verse así:

private String getSignedUrlToPost(String bucketName, String objectName, String mimeType) 
        throws StorageException {
    try {
        Storage storage = StorageOptions.newBuilder().setProjectId("YOUR_PROJECT_ID")
                                        .build().getService();

        // Define Resource
        BlobInfo blobInfo = BlobInfo.newBuilder(BlobId.of(bucketName, objectName))
                                    .build();

        // Generate Signed URL
        Map<String, String> extensionHeaders = new HashMap<>();
        extensionHeaders.put("Content-Type", mimeType);

        //setting it to expire 10 minutes
        return storage.signUrl(
                    blobInfo,
                    10,
                    TimeUnit.MINUTES,
                    Storage.SignUrlOption.httpMethod(HttpMethod.POST),
                    Storage.SignUrlOption.withExtHeaders(extensionHeaders),
                    Storage.SignUrlOption.withV4Signature());
                    
    } catch (StorageException e) {
        throw new StorageException(500,
                "Something went wrong while encoding the URL: "
                e.getMessage());
    }
}

Siempre encuentro que es mejor usar las bibliotecas oficiales, ya que a menudo simplifican su código y es menos propenso a errores, ya que no tiene que averiguar qué se debe hacer detrás de las cortinas.


EDITAR

Para el vencimiento de la URL después de un solo uso, investigué un poco y lo único que pude encontrar es esta pregunta de la comunidad donde la respuesta más votada dice que esto no es posible actualmente.

Aunque es una publicación antigua (más de 5 años), no se menciona que se haya cambiado en la documentación, por lo que supongo que sigue siendo válida. Sugeriría que, para solucionar este problema, haga que la URL tenga un límite de vencimiento de tiempo corto y la ajuste a las necesidades de su aplicación.

NOTA : Puede encontrar más detalles sobre las opciones de las URL firmadas para el almacenamiento en el javadoc para esa clase.

Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.

En caso de infracción, por favor [email protected] Eliminar

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

TOP Lista

  1. 1

    ¿Cómo ocultar la aplicación web de los robots de búsqueda? (ASP.NET)

  2. 2

    Pandas의 CSV 파일을 Pandas 데이터 프레임으로 가져 오기

  3. 3

    uitableview delete button image in iOS

  4. 4

    Manera correcta de agregar referencias al proyecto C # de modo que sean compatibles con el control de versiones

  5. 5

    Swift / Firebase : Facebook 사용자가 계정을 만들 때 Firebase 데이터베이스에 제대로 저장하려면 어떻게해야합니까?

  6. 6

    caída condicional de filas desde un marco de datos de pandas

  7. 7

    Link library in Visual Studio, why two different ways?

  8. 8

    Pagination class not getting applied in html

  9. 9

    Que signifie Decimal (-1)?

  10. 10

    UIButton textLabel with different fonts

  11. 11

    WPF pleine largeur DataGridColumn sur la largeur de DataGrid

  12. 12

    Opción de máquina virtual no reconocida 'MaxPermSize = 512m' cuando se ejecuta Zeppelin

  13. 13

    matplotlib로 그래프를 그리는 동안 커서 위치에서 날짜 / 시간을 볼 수 없습니다. "DateFormatter에서 x = 0 값을 찾았습니다"라는 오류가 발생합니다.

  14. 14

    ¿Es posible en Windows evitar que otras aplicaciones se enganchen en las DLL del sistema?

  15. 15

    Error de la base de datos de Android Firebase: Permiso denegado al depurar en un teléfono

  16. 16

    Pandas: suma filas de DataFrame para columnas dadas

  17. 17

    ggplot2: gráfico con líneas y puntos para problemas de leyenda de dos conjuntos de datos

  18. 18

    ¿Cómo especificar el puerto en el que se aloja una aplicación ASP.NET Core?

  19. 19

    Recherche de la position d'index d'une valeur dans r dataframe

  20. 20

    GPU를 사용하여 ffmpeg 필터의 처리 속도를 가속화하는 방법은 무엇입니까?

  21. 21

    nested observables executed one after the other after termination

CalienteEtiquetas

Archivo