Ben*_*min 17 python openid authentication urllib2
之前已经在这里提出过这个问题.对于提问者和回答者来说,接受的答案可能是显而易见的 - 但不是对我而言.我已就上述问题发表评论以获得更多精确度,但没有回应.我还向meta Q&A索取了关于如何从他们的坟墓中提出问题的帮助,也没有得到答案.
上面问题的答案是:
从客户端的角度来看,OpenID登录与任何其他基于Web的登录非常相似.客户端没有定义的协议; 它是一个普通的Web会话,根据您的OpenID提供程序而有所不同.出于这个原因,我怀疑是否存在任何此类库.您可能需要自己编写代码.
我知道如何使用Urllib2模块登录使用Python的网站.但这还不足以让我猜测如何对OpenID进行身份验证.
我实际上是想以json格式获取我的StackOverflow收件箱,我需要登录.
有人可以提供一个简短的介绍或链接到一个很好的教程如何做到这一点?
Red*_*ron 11
好吧,我自己对OpenID了解不多,但你的帖子(以及赏金!!)让我感兴趣.
此链接指示OpenID身份验证序列的确切流程(Atleast for v1.0.新版本为2.0).根据我的想法,步骤将是类似的
此链接说明OpenID中的各种响应及其含义.因此,当您的代码作为客户端时,它可能会派上用场.
来自维基页面OpenID解释的链接
编辑:使用Tamper Data Add on for Firefox,可以构建以下事件序列.
我建议你开始编写你的python客户端并仔细研究响应.在大多数情况下,它将是一系列302,用户干预最少(填写您的Google用户名和密码并允许网站页面除外).
但是为了方便起见,您可以使用浏览器登录SO,复制所有cookie值并使用urllib2并设置cookie值来发出请求.
当然,如果您在浏览器上注销,则必须再次登录并更改python程序中的cookie值.
我知道这是接近考古学,挖了两年的帖子,但我刚从经过验证的答案中写了一个新的增强版代码,所以我觉得在这里分享它可能很酷,因为这个问题/答案已经有了对我来说是一个很好的帮助来实现它.
所以,这有什么不同:
requests一个增强的新库urllib2;这是代码:
#!/usr/bin/env python
import sys
import urllib
import requests
from BeautifulSoup import BeautifulSoup
def get_google_auth_session(username, password):
session = requests.Session()
google_accounts_url = 'http://accounts.google.com'
authentication_url = 'https://accounts.google.com/ServiceLoginAuth'
stack_overflow_url = 'http://stackoverflow.com/users/authenticate'
r = session.get(google_accounts_url)
dsh = BeautifulSoup(r.text).findAll(attrs={'name' : 'dsh'})[0].get('value').encode()
auto = r.headers['X-Auto-Login']
follow_up = urllib.unquote(urllib.unquote(auto)).split('continue=')[-1]
galx = r.cookies['GALX']
payload = {'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}
r = session.post(authentication_url, data=payload)
if r.url != authentication_url: # XXX
print "Logged in"
else:
print "login failed"
sys.exit(1)
payload = {'oauth_version' : '',
'oauth_server' : '',
'openid_username' : '',
'openid_identifier' : ''}
r = session.post(stack_overflow_url, data=payload)
return session
def get_so_auth_session(email, password):
session = requests.Session()
r = session.get('http://stackoverflow.com/users/login')
fkey = BeautifulSoup(r.text).findAll(attrs={'name' : 'fkey'})[0]['value']
payload = {'openid_identifier': 'https://openid.stackexchange.com',
'openid_username': '',
'oauth_version': '',
'oauth_server': '',
'fkey': fkey,
}
r = session.post('http://stackoverflow.com/users/authenticate', allow_redirects=True, data=payload)
fkey = BeautifulSoup(r.text).findAll(attrs={'name' : 'fkey'})[0]['value']
session_name = BeautifulSoup(r.text).findAll(attrs={'name' : 'session'})[0]['value']
payload = {'email': email,
'password': password,
'fkey': fkey,
'session': session_name}
r = session.post('https://openid.stackexchange.com/account/login/submit', data=payload)
# check if url changed for error detection
error = BeautifulSoup(r.text).findAll(attrs={'class' : 'error'})
if len(error) != 0:
print "ERROR:", error[0].text
sys.exit(1)
return session
if __name__ == "__main__":
prov = raw_input('Choose your openid provider [1 for StackOverflow, 2 for Google]: ')
name = raw_input('Enter your OpenID address: ')
pswd = getpass('Enter your password: ')
if '1' in prov:
so = get_so_auth_session(name, pswd)
elif '2' in prov:
so = get_google_auth_session(name, pswd)
else:
print "Error no openid provider given"
r = so.get('http://stackoverflow.com/inbox/genuwine')
print r.json()
Run Code Online (Sandbox Code Playgroud)
代码也可以作为github gist使用
HTH
这个答案总结了其他人在下面所说的内容,特别是RedBaron,并添加了我用来使用 Google 帐户访问 StackOverflow 收件箱的方法。
使用Firefox的Tamper Data开发者工具并登录StackOVerflow,可以看到OpenID是这样工作的:
上面总结了这个过程,实际上更复杂,因为确实发生了许多重定向和 cookie 交换。
因为以编程方式复制相同的过程被证明有些困难(这可能只是我的文盲),特别是试图寻找要调用的所有区域设置细节等的 URL。我选择首先登录 Google 帐户,获得一个当之无愧的 cookie 并然后登录 Stackoverflow,它将使用 cookie 进行身份验证。
只需使用以下 Python 模块即可完成此操作:urllib、urllib2、cookielib 和 BeautifulSoup。
这是(简化的)代码,它并不完美,但它可以解决问题。扩展版本可以在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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3619 次 |
| 最近记录: |