Questa risposta riassume ciò che altri hanno detto qui di seguito, in particolare RedBaron, più l'aggiunta di un metodo che ho usato per arrivare al StackOverflow Posta in arrivo utilizzando Google Accounts.
Utilizzando lo strumento di sviluppo Tamper Data di Firefox e accesso a StackOverflow, si può vedere che OpenID funziona in questo modo:
- StackOverflow richiede l'autenticazione da un determinato servizio (qui di Google), definito nel postato dati;
- Google Account prende il sopravvento e verifica un cookie già esistente come prova di autenticazione;
- Se non viene trovato alcun cookie, Google richiede l'autenticazione e imposta un cookie;
- Una volta impostato il cookie, StackOverflow riconosce l'autenticazione dell'utente.
Quanto sopra riassume il processo, che in realtà è più complicato, poiché molti reindirizzamenti e scambi di cookie si verificano effettivamente.
Perché la riproduzione dello stesso processo si è dimostrata programmaticamente in qualche modo difficile (e potrebbe essere solo il mio analfabetismo), soprattutto cercando di rintracciare gli URL per chiamare tutte le specifiche locali ecc. Ho optato per l'accesso a Google Account prima, ottenendo un cookie ben meritato e quindi accedere a StackOverflow, che utilizzerebbe il cookie per l'autenticazione.
Questo viene fatto semplicemente utilizzando i seguenti moduli Python: urllib, urllib2, cookielib e BeautifulSoup.
Ecco il codice (semplificato), non è perfetto, ma fa il trucco. La versione estesa può essere trovata su Github.
#!/usr/bin/env python
import urllib
import urllib2
import cookielib
from BeautifulSoup import BeautifulSoup
from getpass import getpass
# Define URLs
google_accounts_url = 'http://accounts.google.com'
authentication_url = 'https://accounts.google.com/ServiceLoginAuth'
stack_overflow_url = 'https://stackoverflow.com/users/authenticate'
genuwine_url = 'https://stackoverflow.com/inbox/genuwine'
# Build opener
jar = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(jar))
def request_url(request):
'''
Requests given URL.
'''
try:
response = opener.open(request)
except:
raise
return response
def authenticate(username='', password=''):
'''
Authenticates to Google Accounts using user-provided username and password,
then authenticates to StackOverflow.
'''
# Build up headers
user_agent = 'Mozilla/5.0 (Ubuntu; X11; Linux i686; rv:8.0) Gecko/20100101 Firefox/8.0'
headers = {'User-Agent' : user_agent}
# Set Data to None
data = None
# Build up URL request with headers and data
request = urllib2.Request(google_accounts_url, data, headers)
response = request_url(request)
# Build up POST data for authentication
html = response.read()
dsh = BeautifulSoup(html).findAll(attrs={'name' : 'dsh'})[0].get('value').encode()
auto = response.headers.getheader('X-Auto-Login')
follow_up = urllib.unquote(urllib.unquote(auto)).split('continue=')[-1]
galx = jar._cookies['accounts.google.com']['/']['GALX'].value
values = {'continue' : follow_up,
'followup' : follow_up,
'dsh' : dsh,
'GALX' : galx,
'pstMsg' : 1,
'dnConn' : 'https://accounts.youtube.com',
'checkConnection' : '',
'checkedDomains' : '',
'timeStmp' : '',
'secTok' : '',
'Email' : username,
'Passwd' : password,
'signIn' : 'Sign in',
'PersistentCookie' : 'yes',
'rmShown' : 1}
data = urllib.urlencode(values)
# Build up URL for authentication
request = urllib2.Request(authentication_url, data, headers)
response = request_url(request)
# Check if logged in
if response.url != request._Request__original:
print '\n Logged in :)\n'
else:
print '\n Log in failed :(\n'
# Build OpenID Data
values = {'oauth_version' : '',
'oauth_server' : '',
'openid_username' : '',
'openid_identifier' : 'https://www.google.com/accounts/o8/id'}
data = urllib.urlencode(values)
# Build up URL for OpenID authetication
request = urllib2.Request(stack_overflow_url, data, headers)
response = request_url(request)
# Retrieve Genuwine
data = None
request = urllib2.Request(genuwine_url, data, headers)
response = request_url(request)
print response.read()
if __name__ == '__main__':
username = raw_input('Enter your Gmail address: ')
password = getpass('Enter your password: ')
authenticate(username, password)
PS: Ho segnalato questo post già per l'attenzione del moderatore in merito alla duplicazione di proposito. – Benjamin