问题
I'm using google picker in my web app to allow user to browse and select files from his google drive. Once he makes the selection, picker returns various data about selected files, including file ID and URL. My goal is to download the selected files to the server. If I pass the URL to my backend script, it won't be able to download a file that is private. I know I could probably use the provided file ID to access the file via Drive API, but I need an access token for that, so I would need to ask the user to grant me permission using oauth flow. I don't want to do that. If user has selected a file using google picker, he is implicitly giving my app the permission to access the file. Why can't I get a public download URL that I can access without a token? That's how Dropbox chooser works, I believe.
Am I missing something here and is there a way to achieve what I'm trying to do without going through oauth authentication. So, basically what I need is this:
- User selects a file using picker
- Picker provides a public download URL (temporary URL is OK)
- I pass that URL to my backend script, which then downloads the file
Alternatively, I could use a solution like this one:
- User selects a file using picker
- Picker provides file ID and an oauth access token
- I pass the file ID and the token to my backend script, which can then access the Google Drive API using the provided access token and download the file.
回答1:
Finally, I found a solution.
If you want to download a file, you need two variables - oAuthToken
and fileId
oAuthToken you get from JS client side when user authenticates. If you use the example from google docs (https://developers.google.com/picker/docs/), the function looks like this:
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
oauthToken; // <-- THIS IS THE Bearer token
createPicker();
}
}
fileId
you get from when user picks a file. Again, a modified example from google docs:
function pickerCallback(data) {
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
alert('You picked fileId: ' + doc[google.picker.Document.ID]);
}
}
Probably you will pass these data as a form request, or through ajax. Simple cURL call from backend to download the file:
$oAuthToken = 'ya29.XXXXXXXXXXXXXXXXXXXXXXXXX-XXXXXXXXX-XXXXXXX-XXXXXX-X-XXXXXXXXXXXX-XXXX';
$fileId = '0B4zzcXXXXXXXXXXXXXXXXXXXXXX';
$getUrl = 'https://www.googleapis.com/drive/v2/files/' . $fileId . '?alt=media';
$authHeader = 'Authorization: Bearer ' . $oAuthToken ;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, [$authHeader]);
$data = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_errno($ch);
$data = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
file_put_contents("destination-file.jpg", $data);
Docs about file download: https://developers.google.com/drive/web/manage-downloads Actually, everything was given to us, but we couldn't move our brains a little to make out the actual code :)
来源:https://stackoverflow.com/questions/19592757/google-picker-and-backend-file-download