2013-03-25 55 views
3

環境 - Python 2.7.3,webpy。通過python oauth2庫的Github api v3訪問 - 重定向問題

我想爲使用Python web.py的github進行簡單的oauth 3方式身份驗證。根據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 

這是送我到GH登錄頁面。一旦我登錄--GH沒有將我重定向到回調。 redirect_uri參數在github應用程序中配置。我仔細檢查過,以確保這是正確的。

class githubCallback: 
    def POST(self): 
    data = web.data() 
    print data 
    def GET(self): 
    print "callback called" 

而是在瀏覽器中我看到 http://<hostname>:8080/session 和404的消息,因爲我還沒有配置會話URL。這是沒有問題1.問題沒有2 - 如果我配置會話URL,並打印出來後消息

class session: 
    def POST(self): 
    data = web.data() 
     print data 
    def GET(self): 
     print "callback called" 

我可以看到張貼的東西叫做「authenticity_token」網址的一些數據。

我試過使用python_oauth2庫,但無法通過authorization_url調用。所以我嘗試了這個更簡單的請求庫。有人可以指出我這裏出了什麼問題。

+0

這是你正在遵循的指南:http://developer.github.com/guides/basics-of-authentication/?你在寫什麼「會話」?這是回調還是別的?此外,您不需要在初始請求中發送客戶端密鑰,只需發送客戶端ID和範圍,以及可選的重定向url:http://developer.github.com/v3/oauth/#web-application -流。您可以在回調處理程序中發送第二個請求中的客戶端密鑰。 – 2013-03-25 10:17:53

+0

@IvanZuzak - 這是使用'http:// developer.github.com/v3/oauth /#web-application-flow'的開發指南Im。 – 2013-03-25 10:26:04

+0

@IvanZuzak對不起,趕快輸入這個開發指南使用'http://developer.github.com/v3/oauth /#web-application-flow'我發送沒有client_secret的請求。同樣的結果。 '/ session'是我在輸入github用戶名密碼後在瀏覽器中看到的URL。 – 2013-03-25 10:32:29

回答

2

我不確定你的問題到底是什麼,但試着重現下面的流程,首先手動使用瀏覽器,然後使用你的python庫。它將幫助您調試問題。

  1. http://requestb.in/上創建請求bin。請求bin基本上是一個記錄發送給它的所有HTTP請求的服務。您將使用此代替回調來記錄正在發送到回調的內容。複製請求斌,這是一樣的東西http://requestb.in/123a546b

  2. 轉到您的OAuth應用程序安裝在GitHub(https://github.com/settings/applications)的網址,輸入您的特定應用程序的安裝,並且回調URL設置爲請求倉的網址你剛創建。

  3. 向GitHub OAuth頁面發出請求,並定義client_id。只需在下面輸入這個網址到瀏覽器,但改變YOUR_CLIENT_ID_HERE是您的OAuth應用程序的客戶端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」(這是請求bin服務返回的內容)。

  5. 轉到您創建的請求bin頁面並刷新它。您現在將看到GitHub OAuth服務器發送給您的HTTP GET請求的日誌條目以及所有HTTP標頭。基本上,您會看到與您重定向到的URL中存在相同的代碼參數。如果你得到這個參數,你現在願意與這個代碼和客戶端密鑰POST請求,因爲在引導步驟2中使用的是:http://developer.github.com/v3/oauth/#web-application-flow

讓我知道如果任何這些步驟對您造成問題。

+0

這個流程很完美。我在python流程中做的幾乎是一樣的,而且是扯皮。感謝您的投入。我會看看Python庫出了什麼問題。 – 2013-03-25 11:21:22

+0

這真的很奇怪。我建議你也嘗試使用普通的Python HTTP庫來發送HTTP請求,就像你通過瀏覽器(例如http://docs.python-requests.org/en/latest/)一樣發送HTTP請求,或者使用一個用於GitHub的Python庫通常可以正確處理OAuth流(http://developer.github.com/v3/libraries/#python)。無論如何,讓我們知道你什麼時候發現了什麼bug :)。 – 2013-03-25 11:26:21

+0

我正在使用python請求庫。但是這次我做了一個簡單的改變。我不是從服務器發送登錄請求,而是從HTML頁面發送,使用模板呈現。這工作。我將在答案部分進一步闡述。 – 2013-03-25 16:09:20

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來指導用戶從他登錄到gh的地方開始。有了這個,我添加了一個html,並使用templator呈現它。

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進行序列化。