Question

I'm having a difficult time getting the 'Simple Upload' method in the GCS JSON API to work in Python. The documentation (https://developers.google.com/storage/docs/json_api/v1/how-tos/upload#simple) makes it appear trivial, but I can't get past authorization. I don't fully understand authorization/authentication/keys/tokens, but I'm trying. The bucket(s) that I've been trying to upload to allow for full read-write (they're public), and I've generated and tried every combination and permutation of keys I can think of.

My code:

def postTest():
  headers = {'Host':'www.googleapis.com','Authorization':'Bearer? WHATGOESINHERE?','Content-Length': 0, 'Content-Type': "text/plain"}
  files = {'file': ('report.txt', 'justsomeblankityblanktext\n')}

  r = requests.post("https://storage.googleapis.com/upload/storage/v1beta2/b/NOTACTUALLYAREALBUCKETOBVIOUSLY/o?uploadType=media&name=testi.txt", headers=headers, files=files)

  print(r.request.headers)
  print(r.url)
  print(r.text)

And the response:

CaseInsensitiveDict({'Content-Length': '172', 'Accept-Encoding': 'gzip, deflate, compress', 'Accept': '*/*', 'User-Agent': 'python-requests/2.2.1 CPython/2.7.6 Darwin/13.1.0', 'Host': 'www.googleapis.com', 'Content-Type': 'text/plain', 'Authorization': 'Bearer? WHATGOESINHERE?'})
https://storage.googleapis.com/upload/storage/v1beta2/b/NOTACTUALLYAREALBUCKETOBVIOUSLY/o?uploadType=media&name=testi.txt
{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "authError",
    "message": "Invalid Credentials",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Invalid Credentials"
 }
}

So, my question is in regards to the 'Authorization' key-value pair in the headers. What sort of an 'authorization token' should be included?

Was it helpful?

Solution

OAuth2 authorization is a bit tricky. The idea is that, instead of using your real password all the time for everything, you use your password once to get a temporary code that works for the next hour or so. Then you use that code for everything, and if for some reason it's compromised, it will stop working in an hour or so anyway. To add even more complication, OAuth also allows you to ask for credentials to act as an end user (for example, if you were making a cloud storage viewer on the web, you might want to let people login, but you don't want to know their Google password).

The way you get the access token is by asking Google's OAuth2 service for one. You can do this in a few ways, depending on how you want to authorize. If your app always acts as itself, you can download a private key for it that it can use to create an assertion. Here're the instructions for this.

Another common use case is an app that acts as you. In this case, you would create a link to a login URL, have the user navigate there and log in, and then your app will receive back a key (or the user will get a key to paste into your app) that will give you a permanent "refresh token" that you can use to ask for a new access token whenever you need. Instructions for installed apps are here.

There are a few other kinds of things as well. Ultimately it's somewhat complicated, which is why Google provides a Python client that can take care of OAuth2 authorization for you. You'll still need to think about what kind of auth you want to use, but the Google APIs Python Library can take care of most of the messy details.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top