1

We're creating a form that allows users to upload large files. On mobile devices and slow connections, it might take a while to upload, so it seems important for this to be handled by an AJAX call that shows the users a progress bar (or something to let them know it's still working).

Here's the problem: The endpoint for the upload is a 3rd party API which expects our secret API key as one of the parameters. Here's a link directly to the section in their documentation. This API key cannot be exposed to the users on the client side.

My first instinct is to submit the form to an intermediate PHP script on our site, which has the API key, and then uploads the file to the API. But I'm pretty sure this will mean uploading the file twice: once to our server. Then again from our server to the API endpoint. Even if the form is submitted with AJAX, it's not a great result for the user to wait twice as long for it to complete.

So: What's the smoothest way to let users upload files while keeping our API key safe?

Some details that may or may not be important:
Our site is a PHP web app built on the CakePHP framework (v2.x). The files being uploaded are video files of all different formats between 1 and 5 minutes long. The API is a company called Wistia (see link to docs above). The file sizes seem to range from 3-30MB. We have no ability to change the way the 3rd party API works.

emersonthis
  • 32,822
  • 59
  • 210
  • 375
  • How do you have to pass the parameter to the API? By PHP? By Javascript as a param in a URL? I don't have very clear why should it be public and not hidden in the PHP side. – Alvaro Jul 25 '13 at 14:55
  • The Ajax-request will be sent to directly the 3rd party? – Pieter Jul 25 '13 at 14:55
  • @Alvaro I added the link to the authorization options in their docs. – emersonthis Jul 25 '13 at 15:45
  • @Pieter The question you're asking is the question I'm asking. Ideally the AJAX request would go straight there, but I don't know how to do it without exposing our API key to the client. – emersonthis Jul 25 '13 at 15:45

3 Answers3

0

Uploading twice shouldn't be an issue - should it?

Its from your server to their API - this is what servers and APIs are meant for - exchanging data.

Javascript is not meant for this.

Jake N
  • 10,535
  • 11
  • 66
  • 112
  • Uploading twice is fine, but making the uploader wait twice as long to upload a big file on a slow connection is a bummer. I can't really store the files and queue them for upload to the API because the API does certain validation that needs to be passed back to the user at the point of upload. – emersonthis Jul 25 '13 at 15:48
  • Make the second upload from server to API a background task. No need for the user to be aware of that. – Jake N Jul 25 '13 at 16:20
  • That's exactly the kind of thing I'm interested in figuring out. I've never done that before. Could you explain a bit how that might work? – emersonthis Jul 25 '13 at 17:20
  • That is another question entirely http://stackoverflow.com/questions/858883/run-php-task-asynchronously – Jake N Jul 25 '13 at 18:11
  • I think I misunderstood what you initially said. I took a look at the link and it's neat stuff, but I can't upload the file silently in the background because the uploader needs to know if it succeeded or not. – emersonthis Jul 25 '13 at 18:23
0

There is no way to hide it on the client, so your first instinct was correct - you will need to forward the file from the server.

BigBadOwl
  • 669
  • 2
  • 9
  • 22
0

It should be possible to read raw post stream from php://input, you can get the uploaded file from there (if you can parse it :)) and start upload to api server right away.

But even if the communication between mobile device and your script is slow, your script likely will likely upload fast to api server. So is it really needed?

Marek
  • 7,337
  • 1
  • 22
  • 33
  • I'm very interested to hear more about reading the raw post stream. I've never done it before. Can you give an example of this? Or a link to something? – emersonthis Jul 25 '13 at 15:50
  • Now I found out that this does not work for multipart/form-data. – Marek Jul 26 '13 at 09:30