I cannot get the upload on a Google Cloud Signed URL to work. I get the same SignatureDoesNotMatch error.
I tried lots of things including:
- deactivating the v4 for the v2
- adding or removing content type
- changing fetch with axios
- using Postman
- try to be a wizard with POST and then PUT and
x-goog-resumable:start
- change the CORS of my bucket
- increasing the timeout
I just never get the upload to work.
The token creation code:
public static String generateV4PutObjectSignedUrl(String objectName) throws StorageException {
// String projectId = "my-project-id";
// String bucketName = "my-bucket";
// String objectName = "my-object";
Storage storage = StorageOptions.getDefaultInstance().getService();
// Define Resource
BlobInfo blobInfo = BlobInfo.newBuilder(BlobId.of("mybucket", objectName)).build();
// Generate Signed URL
Map<String, String> extensionHeaders = new HashMap<>();
extensionHeaders.put("Content-Type", "application/octet-stream");
URL url = storage.signUrl(
blobInfo,
15,
TimeUnit.HOURS,
Storage.SignUrlOption.httpMethod(HttpMethod.PUT),
Storage.SignUrlOption.withExtHeaders(extensionHeaders),
Storage.SignUrlOption.withV4Signature()
);
String urlS = url.toString();
System.out.println("Generated PUT signed URL:"+urlS);
return urlS;
}
then the CORS of the bucket:
[{"maxAgeSeconds": 3600000, "method": ["GET", "PUT", "OPTIONS", "POST"], "origin": ["LIVE", "http://localhost:8080", "http://0.0.0.0:8080"], "responseHeader": ["Content-Type", "x-goog-resumable"]}]
And then my attempts to put:
const signedUrl = await fetch("$STORAGE_FUN/" + apkFile.name.replace(" ", "_")).then((res) => res.text());
await axios.put(signedUrl, apkFile);
As well as:
const put = await fetch(signedUrl, {
method: 'PUT',
headers: {'Content-Type': 'application/octet-stream'},
body: apkFile
})
As well as:
curl --location --request PUT 'https://storage.googleapis.com/mybucket/no-heroes-here.apk?GoogleAccessId=autodeploy@company.iam.gserviceaccount.com&Expires=1676643070&Signature=ZYU7CjzWRcKaqjOufUZ%2BkOJA%2FsB1vVpWBZAfpeUKIrmQRHJ6ZgXE7bwmqtaIWwBCbZv%2Fa1naYV3xC2OMqhpZ7ene46ZWS4JH%2FIvVn2U5SMBjYG38SrKqICLfj3l4sN%2BR39ijTxPwP4nWCpvMm39CxtCZAC6n5FovsNterZ7NqByXHP7YXgzOXeiBALabDv%2B%2BnclpVtoJ4K6h%2ByFKyQ6odzT0PTDIvpED4ph%2BIrdptwxraFFpLNL8k0ocAsd1zn9U4cxRrTTFCMzzMaXdhXRfVAtkSl5NW7BosdkRmgGtB%2FA1TEifea%2BnfXyXtbRaW7QG5TA9WxrA3VmHNMWz3At29A%3D%3D' \
-H 'Content-Type:' \
--data-binary '@/somepath/original/noheroeshere/no-heroes-here.apk'
And we get a similar error as:
<?xml version='1.0' encoding='UTF-8'?>
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message>
<StringToSign>GOOG4-RSA-SHA256
20230216T232500Z
20230216/auto/storage/goog4_request
338a1267c21129d5a991a59881cf42c0112f6cfd5cc067c162e0716adc059d5e</StringToSign>
<CanonicalRequest>PUT
/mybucket/no-heroes-here.apk
X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=autodeploy%40company.iam.gserviceaccount.com%2F20230216%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20230216T232500Z&X-Goog-Expires=54000&X-Goog-SignedHeaders=content-type%3Bhost
content-type:application/octet-stream
host:storage.googleapis.com
content-type;host
UNSIGNED-PAYLOAD</CanonicalRequest>
</Error>
Many questions:
- Do you see an obvious error in my code?
- Is there a way to debug the Signature Error like some logs in the bucket that where we could see what is actually not matching?
- Can it be a permission problem of the service account that I'm using?
- Would the URL be generated if the service account wouldn't work?