Hansen W
Hansen W

Reputation: 1098

Google Cloud Storage - How to upload images with Vue through frontend

I have an app with frontend build in Vue and backend in express, I have a function where I can upload images for my website. Right now I am using cloudinary, which is very easy to use, I can just do the upload on the frontend with:

<upload action=https://api.cloudinary.com/v1_1/devenv/image/upload></upload>

and it would return the URL which I can use for serving the images.

I was wondering if there is a similar URL for Google Cloud Storage, I looked up the documentation, the recommended way is to use the nodejs client. So do I have to write an endpoint at the backend for this upload to work?

Also, another problem with backend upload is authentication Google client use a JSON file for auth, this is okay for development, but what should I do for production if my backend is running on GCP kubernetes engine, is there any way that I can connect them together without putting the JSON file in the Docker container?

Help and code samples will be really appreciated!!

Upvotes: 1

Views: 3656

Answers (1)

Diego Caldeira
Diego Caldeira

Reputation: 471

To allow users to upload objects to GCS via a form POST, you're going to need to create a "policy document" describing what sort of objects the user can upload, then sign it, then pass that signed doc as a parameter in the form. You can read more about uploading to GCS via a POST here: https://cloud.google.com/storage/docs/xml-api/post-object

And note especially the section on signed policy documents here: https://cloud.google.com/storage/docs/xml-api/post-object#policydocument

Here's an example policy document:

{
 "expiration": "2010-06-16T11:11:11Z",
 "conditions": [
  ["starts-with", "$key", "" ],
  {"acl": "bucket-owner-read" },
  {"bucket": "travel-maps"},
  {"success_action_redirect": "http://www.example.com/success_notification.html" },
  ["eq", "$Content-Type", "image/jpeg" ],
  ["content-length-range", 0, 1000000]
  ]
}

You'd then base64 that document, sign the result with the private key for the service account you want the user to act as for purposes of the upload, and then provide them in hidden fields, like this:

<input type="hidden" name="policy" value="eyJleHBpcmF0aW9uIjogIjIwMTAtMDYtMTZUMTE6MTE6MTFaIiwNCiAiY29uZGl0aW9ucyI6IFsNCiAgWyJzdGFydHMtd2l0aCIsICJrZXkiLCAiIiBdLA0KICB7ImFjbCI6ICJidWNrZXQtb3duZXItcmVhZCIgfSwNCiAgeyJidWNrZXQiOiAidHJhdmVsLW1hcHMifSwNCiAgeyJzdWNjZXNzX2FjdGlvbl9yZWRpcmVjdCI6ICJodHRwOi8vd3d3LmV4YW1wbGUuY29tL3N1Y2Nlc3Nfbm90aWZpY2F0aW9uLmh0bWwiIH0sDQogIFsiZXEiLCAiQ29udGVudC1UeXBlIiwgImltYWdlL2pwZWciIF0sDQogIFsiY29udGVudC1sZW5ndGgtcmFuZ2UiLCAwLCAxMDAwMDAwXQ0KICBdDQp9">
<input type="hidden" name="signature" value="BSAMPLEaASAMPLE6SAMPLE+SAMPPLEqSAMPLEPSAMPLE+SAMPLEgSAMPLEzCPlgWREeF7oPGowkeKk7J4WApzkzxERdOQmAdrvshKSzUHg8Jqp1lw9tbiJfE2ExdOOIoJVmGLoDeAGnfzCd4fTsWcLbal9sFpqXsQI8IQi1493mw=">

The policy document is a JSON string that has been encoded using base64 and is passed to GCS as part of the POST request as a hidden input. You can either declare it as a constant in your code, or else you could generate one using a JSON and a base64 library on the fly.

Upvotes: 2

Related Questions