通过Python OAuth2库访问Github API v3 - 重定向问题
环境 - Python 2.7.3,使用webpy框架。
我正在尝试用Python的web.py做一个简单的GitHub三步认证。根据GitHub的基本oauth指南,我大致是这么做的:
import web,requests
import oauth2,pymongo,json
from oauth2client.client import OAuth2WebServerFlow
urls=('/', 'githublogin',
'/session','session',
'/githubcallback','githubCallback');
class githublogin:
def GET(self):
new_url = 'https://github.com/login/oauth/authorize'
pay_load = {'client_id': '',
'client_secret':'',
'scope':'gist'
}
headers = {'content-type': 'application/json'}
r = requests.get(new_url, params=pay_load, headers=headers)
return r.content
这段代码会把我带到GitHub的登录页面。一旦我登录了,GitHub却没有把我重定向回我设置的回调地址。重定向的地址参数在GitHub应用中已经配置好了。我仔细检查过,确认没有问题。
class githubCallback:
def POST(self):
data = web.data()
print data
def GET(self):
print "callback called"
但在浏览器中我看到的是
http://<hostname>:8080/session
和一个404错误信息,因为我还没有配置会话的URL。这是第一个问题。第二个问题是 - 如果我配置了会话的URL并打印出提交的信息
class session:
def POST(self):
data = web.data()
print data
def GET(self):
print "callback called"
我能看到一些数据被发送到这个URL,其中有个东西叫做‘authenticity_token’。
我尝试使用python_oauth2库,但在authorization_url调用时遇到了问题。所以我试了一个更简单的requests库。有人能告诉我这里出了什么问题吗?
2 个回答
这是我解决问题的方法。感谢@Ivanzuzak提供的requestb.in建议。
我在使用Python的webpy框架。
import web,requests
import oauth2,json
urls=('/', 'githublogin',
'/githubcallback','githubCallback');
render = web.template.render('templates/')
class githublogin:
def GET(self):
client_id = ''
url_string = "https://github.com/login/oauth/authorize?client_id=" + client_id
return render.index(url_string)
class githubCallback:
def GET(self):
data = json.loads(json.dumps(web.input()))
print data['code']
headers = {'content-type': 'application/json'}
pay_load = {'client_id': '',
'client_secret':'',
'code' : data['code'] }
r = requests.post('https://github.com/login/oauth/access_token', data=json.dumps(pay_load), headers=headers)
token_temp = r.text.split('&')
token = token_temp[0].split('=')
access_token = token[1]
repo_url = 'https://api.github.com/user?access_token=' + access_token
response = requests.get(repo_url)
final_data = response.content
print final_data
app = web.application(urls,globals())
if __name__ == "__main__":
app.run()
之前我没有使用html文件,而是直接从githublogin类发送请求。这样做不行。现在我使用了一个html文件,先引导用户登录GitHub。通过这个方法,我添加了一个html文件,并使用模板引擎来渲染它。
def with (parameter)
<html>
<head>
</head>
<body>
<p>Well, hello there!</p>
<p>We're going to now talk to the GitHub API. Ready? <a href=$parameter>Click here</a> to begin!</a></p>
<p>If that link doesn't work, remember to provide your own <a href="http://developer.github.com/v3/oauth/#web-application-flow">Client ID</a>!</p>
</body>
</html>
这个文件直接来自开发指南,只是修改了client_id参数。
还有一点需要注意的是,在requests.post方法中,直接传递pay_load是行不通的。必须先用json.dumps进行序列化。
我不太确定你那边的问题是什么,但你可以试着按照下面的步骤来操作,先用浏览器手动执行一次,然后再用你的 Python 库来做。这会帮助你找到问题所在。
在 http://requestb.in/ 上创建一个请求箱。请求箱基本上是一个可以记录所有发送给它的 HTTP 请求的服务。你将用这个来代替回调,记录发送到回调的内容。复制请求箱的 URL,类似于 http://requestb.in/123a546b 这样的链接。
去 GitHub 的 OAuth 应用设置页面 (https://github.com/settings/applications),进入你特定应用的设置,把回调 URL 设置为你刚创建的请求箱的 URL。
向 GitHub 的 OAuth 页面发起请求,记得要定义 client_id。只需在浏览器中输入下面的 URL,但把 YOUR_CLIENT_ID_HERE 替换成你 OAuth 应用的 client id:
https://github.com/login/oauth/authorize?client_id=YOUR_CLIENT_ID_HERE
输入你的用户名和密码,然后点击授权。GitHub 应用会把你重定向到你创建的请求箱服务,浏览器中的 URL 应该类似于(注意代码查询参数):
http://requestb.in/YOUR_REQUEST_BIN_ID?code=GITHUB_CODE
(例如,
http://requestb.in/abc1def2?code=123a456b789cdef
)另外,浏览器页面的内容应该是 "ok"(这是请求箱服务返回的内容)。
去你创建的请求箱页面并刷新一下。你现在会看到一个日志条目,记录了 GitHub OAuth 服务器发送给你的 HTTP GET 请求,以及所有的 HTTP 头信息。基本上,你会在这里看到和你被重定向到的 URL 中相同的代码参数。如果你得到了这个参数,你现在就可以准备好使用这个代码和你的客户端密钥发起 POST 请求,按照你正在使用的指南的第 2 步进行操作: http://developer.github.com/v3/oauth/#web-application-flow
如果这些步骤中有任何问题,请告诉我。