通过Python OAuth2库访问Github API v3 - 重定向问题

3 投票
2 回答
1800 浏览
提问于 2025-04-17 20:12

环境 - 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 个回答

3

这是我解决问题的方法。感谢@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进行序列化。

2

我不太确定你那边的问题是什么,但你可以试着按照下面的步骤来操作,先用浏览器手动执行一次,然后再用你的 Python 库来做。这会帮助你找到问题所在。

  1. http://requestb.in/ 上创建一个请求箱。请求箱基本上是一个可以记录所有发送给它的 HTTP 请求的服务。你将用这个来代替回调,记录发送到回调的内容。复制请求箱的 URL,类似于 http://requestb.in/123a546b 这样的链接。

  2. 去 GitHub 的 OAuth 应用设置页面 (https://github.com/settings/applications),进入你特定应用的设置,把回调 URL 设置为你刚创建的请求箱的 URL。

  3. 向 GitHub 的 OAuth 页面发起请求,记得要定义 client_id。只需在浏览器中输入下面的 URL,但把 YOUR_CLIENT_ID_HERE 替换成你 OAuth 应用的 client id:

    https://github.com/login/oauth/authorize?client_id=YOUR_CLIENT_ID_HERE

  4. 输入你的用户名和密码,然后点击授权。GitHub 应用会把你重定向到你创建的请求箱服务,浏览器中的 URL 应该类似于(注意代码查询参数):

    http://requestb.in/YOUR_REQUEST_BIN_ID?code=GITHUB_CODE

    (例如,http://requestb.in/abc1def2?code=123a456b789cdef

    另外,浏览器页面的内容应该是 "ok"(这是请求箱服务返回的内容)。

  5. 去你创建的请求箱页面并刷新一下。你现在会看到一个日志条目,记录了 GitHub OAuth 服务器发送给你的 HTTP GET 请求,以及所有的 HTTP 头信息。基本上,你会在这里看到和你被重定向到的 URL 中相同的代码参数。如果你得到了这个参数,你现在就可以准备好使用这个代码和你的客户端密钥发起 POST 请求,按照你正在使用的指南的第 2 步进行操作: http://developer.github.com/v3/oauth/#web-application-flow

如果这些步骤中有任何问题,请告诉我。

撰写回答