What Is The Correct Mechanism To Authenticate To Google In A Standalone Python Script?
Solution 1:
It ended up being easier to just hack together a shell script using curl than mess with the gdata library. As expected, I was able to do most of the verification process manually, outside of the script, per the OAuth2 Device Flow instructions.
After finishing the verification process, I had the 4 required credentials: the client id, the client secret, the access token, and the refresh token. Per Google's documentation, the access token eventually expires. You can get a new access token by asking the token manager to refresh the token. When you do this, you apparently get a new access token, but not a new refresh token.
I store the client id and secret and the refresh token in the CREDENTIALS
file in JSON format. Since the access token changes over time, it is stored in the ACCESS
file, also in JSON format.
The important parts of the script are shown below:
#!/bin/ksh
CLIENT_ID=$(cat${CREDENTIALS} | jq -r ".client_id")
CLIENT_SECRET=$(cat${CREDENTIALS} | jq -r ".client_secret")
REFRESH_TOKEN=$(cat${CREDENTIALS} | jq -r ".refresh_token")
ACCESS_TOKEN=$(cat${ACCESS} | jq -r ".access_token")
CONTACTS_URL="https://www.google.com/m8/feeds/contacts/default/full?access_token=${ACCESS_TOKEN}&max-results=5000&v=3.0"
ERROR=$(curl --show-error --silent --fail "${CONTACTS_URL}" -o ${CONTACTS_XML} 2>&1)
RESULT=$?
if [[ ${RESULT} -eq 0 ]]
thencat${CONTACTS_XML} | grep 'gd:email' | sed 's/^.*address="//g' | sed 's/".*$//g' | tr'[:upper:]''[:lower:]' | sort | uniqelif [[ ${RESULT} -eq 22 ]]
thenecho"${ERROR}" | grep -q "401"if [[ $? -eq 0 ]]
then
TOKEN_URL="https://www.googleapis.com/oauth2/v3/token"
REFRESH_PARAMS="client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&refresh_token=${REFRESH_TOKEN}&grant_type=refresh_token"
ERROR=$(curl --show-error --silent --fail --data "${REFRESH_PARAMS}"${TOKEN_URL} -o ${REFRESH_JSON})
RESULT=$?
if [[ ${RESULT} -eq 0 ]]
then
ACCESS_TOKEN=$(cat${REFRESH_JSON} | jq -r ".access_token")
jq -n --arg access_token "${ACCESS_TOKEN}"'{"access_token": $access_token, }' > ${ACCESS}
CONTACTS_URL="https://www.google.com/m8/feeds/contacts/default/full?access_token=${ACCESS_TOKEN}&max-results=5000&v=3.0"
ERROR=$(curl --show-error --silent --fail "${CONTACTS_URL}" -o ${CONTACTS_XML} 2>&1)
RESULT=$?
if [[ ${RESULT} -eq 0 ]]
thencat${CONTACTS_XML} | grep 'gd:email' | sed 's/^.*address="//g' | sed 's/".*$//g' | tr'[:upper:]''[:lower:]' | sort | uniqelseprint"Unexpected error: ${ERROR}" >&2
exit 1
fielseprint"Unexpected error: ${ERROR}" >&2
exit 1
fielseprint"Unexpected error: ${ERROR}" >&2
exit 1
fielseprint"Unexpected error: ${ERROR}" >&2
exit 1
fi
It's not the prettiest thing in the world, but I was looking for something quick-and-dirty, and this works.
Solution 2:
Can someone please suggest the proper way to do this in a standalone script? Or am I out of luck and there's no mechanism to accomplish this any more?
There's no mechanism any more like the one you are using. You will have to set up a Cloud Developer project and use OAuth2, and rewrite your script.
To make it as futureproof as possible, you could switch to the newest Contacts API. With this API, you can use the OAuth2 Device flow, which might be simpler for your use case.
Not the answer you were hoping to hear, I know, but I think it's the only answer.
Post a Comment for "What Is The Correct Mechanism To Authenticate To Google In A Standalone Python Script?"