11

i am fairly new to programming for web. and i want to start from scratch here. i tried to search the net but ended up completely confused. now what i want to learn is how to authenticate a google account through a python script. can anyone please provide me with a code fragment or any example.

thanks a lot in advance.

1
  • I've been working on the same thing all day, hope to have something working soon.CommentedApr 8, 2011 at 8:09

5 Answers 5

19

I spent a whole day on coding this, after several failed attempts over the past few weeks. This only gets you as far as the first step, but it does so without any external libraries. And yes, I know it's close to two years after the OP, but from what I could see it still needed to be done.

 #!/usr/bin/python 'demo Google OAuth' import sys, os, urllib, urllib2, time, httplib import hmac, hashlib, random, re, base64 PARAMETERS = { 'oauth_consumer_key': os.getenv('OAUTH_CONSUMER_KEY') or 'anonymous', 'oauth_signature_method': 'HMAC-SHA1', 'oauth_signature': '', 'oauth_timestamp': os.getenv('OAUTH_TIMESTAMP') or '%d' % time.time(), 'oauth_nonce': os.getenv('OAUTH_NONCE') or '%x' % random.getrandbits(64), 'oauth_version': '1.0', 'oauth_callback': os.getenv('OAUTH_CALLBACK') or 'callback', } SCOPE = {'scope': 'https://www.google.com/calendar/feeds/'} SECRET = os.getenv('OAUTH_CONSUMER_SECRET') or 'anonymous' def google_oauth(): 'OAuthGetRequestToken, OAuthAuthorizeToken, OAuthGetAccessToken' request_token = get_request_token() return request_token def get_request_token(): 'ask Google for a request token' url = 'https://www.google.com/accounts/OAuthGetRequestToken' token_secret = '' # we don't have a token secret yet PARAMETERS['oauth_signature'] = sign('&'.join((SECRET, token_secret)), '&'.join(map(urlencode, ('GET', url, parameters('signing'))))) body = urllib.urlencode(SCOPE) request = urllib2.Request(url + '?' + body) request.add_header('Authorization', 'OAuth ' + parameters('header')) opener = urllib2.build_opener(urllib2.HTTPSHandler(debuglevel = 1)) response = opener.open(request) reply = response.read() response.close() return reply def byte_encode(match): 'for use with re.sub' return '%%%02X' % ord(match.group()) def urlencode(string): "unreserved = ALPHA, DIGIT, '-', '.', '_', '~'" return re.sub(re.compile('[^0-9A-Za-z._~-]'), byte_encode, string.encode('utf8')) def sign(secret, text): print >>sys.stderr, 'signature base string: "%s", secret: %s' % ( repr(text), repr(secret)) digest = hmac.new(secret, text, hashlib.sha1).digest() return urlencode(base64.encodestring(digest).rstrip()) def base64string(hexstring): recoded = urlencode(base64.encodestring(hexstring.decode('hex')).rstrip()) print >>sys.stderr, 'recoded:', recoded return recoded def parameters(format): if format == 'header': formatted = ', '.join(['%s="%s"' % (key, value) for key, value in PARAMETERS.items()]) elif format == 'signing': formatted = '&'.join(sorted(['%s=%s' % (key, urlencode(value.encode('utf8'))) for key, value in (PARAMETERS.items() + SCOPE.items()) if key not in ['oauth_signature']])) #print >>sys.stderr, format, formatted return formatted def hmac_sha1_test(): 'from tools.ietf.org/html/rfc2202' assert sign('\x0b' * 20, 'Hi There') == base64string( 'b617318655057264e28bc0b6fb378c8ef146be00') assert sign('Jefe', 'what do ya want for nothing?') == base64string( 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79') assert sign('\xaa' * 20, '\xdd' * 50) == base64string( '125d7342b9ac11cd91a39af48aa17b4f63f175d3') # last test from http://oauth.net/core/1.0/#rfc.section.9.1.1, app. A.5.2 assert sign('kd94hf93k423kf44&pfkkdhi9sl3r4s00', 'GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26' + \ 'oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3D' + \ 'kllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26' + \ 'oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26' + \ 'oauth_version%3D1.0%26size%3Doriginal') == urlencode( 'tR3+Ty81lMeYAr/Fid0kMTYa/WM=') return True if __name__ == '__main__': command = os.path.splitext(os.path.basename(sys.argv[0]))[0] print eval(command)(*sys.argv[1:]) 

Save it as google_oauth.py, and you can link to it like so:

ln -s google_oauth.py hmac_sha1_test.py
to test any of the subroutines. Combined with the use of environment variables, you can compare your results with those of Google's OAuth Playground (other folks here provided the link) and see where you are going wrong. I found many problems with the script that way; there may well be many more. But if you invoke ./google_oauth.py, you should see something like this:

 jcomeau@intrepid:~/rentacoder/marchie$ ./google_oauth.py signature base string: "'GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_callback%3Dcallback%26oauth_consumer_key%3Danonymous%26oauth_nonce%3Da64720fda018906b%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1302253695%26oauth_version%3D1.0%26scope%3Dhttps%253A%252F%252Fwww.google.com%252Fcalendar%252Ffeeds%252F'", secret: 'anonymous&' send: 'GET /accounts/OAuthGetRequestToken?scope=https%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2F HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: www.google.com\r\nConnection: close\r\nAuthorization: OAuth oauth_nonce="a64720fda018906b", oauth_timestamp="1302253695", oauth_consumer_key="anonymous", oauth_signature_method="HMAC-SHA1", oauth_version="1.0", oauth_signature="LSJxopFXWN71sTSIBIkNeGgsOjc%3D", oauth_callback="callback"\r\nUser-Agent: Python-urllib/2.6\r\n\r\n' reply: 'HTTP/1.1 200 OK\r\n' header: Content-Type: text/plain; charset=UTF-8 header: Date: Fri, 08 Apr 2011 09:08:20 GMT header: Expires: Fri, 08 Apr 2011 09:08:20 GMT header: Cache-Control: private, max-age=0 header: X-Content-Type-Options: nosniff header: X-XSS-Protection: 1; mode=block header: Content-Length: 118 header: Server: GSE header: Connection: close oauth_token=4%2FfvSIWW9WBHXa_CjInpOf4FdNYhCj&oauth_token_secret=qhB1EGIKjL1pG9POF2ZOcQk3&oauth_callback_confirmed=true 
2
  • 1
    Nice content to build from. To clean it a little I think the assignment in request = opener.open(request) should read response = opener.open(request) and response should replace request in the subsequent 2 lines
    – Brad M
    CommentedApr 20, 2015 at 12:23
  • good point. hard to say what was going on in my head that day.CommentedApr 21, 2015 at 14:13
2

try this example

1
  • 404, this is why link-only answers are badCommentedMar 3 at 20:13
1

Good intro: http://code.google.com/apis/accounts/docs/OAuth.html

Great working, playable example: http://googlecodesamples.com/oauth_playground/

    0

    See the document on Google Data API docs:

    There's a ClientLogin sample under "Hello World".

      0

      Some good links above (the playground is invaluable).

      I use a mixture of Leah Culver's oAuth code (the example in b3rx's post) and FireEagle's Python OAuth code. The former, the last time I looked, was lacking scope methods.

      Also, make sure you are clear on whether you are using 2 or 3 legged OAuth:

        Start asking to get answers

        Find the answer to your question by asking.

        Ask question

        Explore related questions

        See similar questions with these tags.