2016-10-02 47 views
1

目標是交換訪問和刷新令牌的授權碼。對Feedly API的授權請求會使用Guzzle拋出一個錯誤的請求?

錯誤:

GuzzleHttp\Exception\ClientException #400 

Client error response 
[url] http://sandbox.feedly.com/v3/auth/token?code=[auth_code]&client_id=sandbox&client_secret=[secret]&redirect_uri=https%253A%252F%252F[site url]&grant_type=authorization_code&state=%23 
[status code] 400 
[reason phrase] Bad Request 

相關代碼:

$client = new GuzzleHttp\Client(); 
$parameters = ['code'=>$_GET['code'],'client_id'=>'sandbox','client_secret'=> '[secret]','redirect_uri'=>urlencode('https://[site url]'),'grant_type'=>'authorization_code', 'state'=>'#']; 
$params = http_build_query($parameters); 
$request = $client->createRequest('POST', 'http://sandbox.feedly.com/v3/auth/token?'.$params); 
$request->addHeader('Accept-Encoding','GZIP'); 
$request->setHeader('Authorization', "auth-code"); 
$request->addHeader('Content-Type','application/json'); 
$response = $client->send($request); 
var_dump($response->json()); 

state = "state.passed.in"也試過,但會引發同樣的錯誤。

你能指出代碼片段中的錯誤嗎?它使用Feedly API v3沙盒和Guzzle HTTP客戶端。

如果跟隨請求URL,它會拋出「不允許」。

更新程式碼:

$client = new GuzzleHttp\Client(); 
    $parameters = ['code'=>$_GET['code'],'client_id'=>'sandbox','client_secret'=> '[secret]','redirect_uri'=>urlencode('https://[site url]'),'grant_type'=>'authorization_code', 'state'=>'#']; 
    $params = http_build_query($parameters); 
    $request = $client->createRequest('POST', 'http://sandbox.feedly.com/v3/auth/token?'.$params); 
    $response = $client->send($request); 
    var_dump($response->json()); 

錯誤的更新代碼:

GuzzleHttp\Exception\ServerException #522 

Server error response [url] http://sandbox.feedly.com/v3/auth/token?code=[auth_code]&client_id=sandbox&client_secret=[secret]&redirect_uri=https%253A%252F%252F[site url]&grant_type=authorization_code&state=%23 
[status code] 522 
[reason phrase] Origin Connection Time-out 

注:更新代碼拋出了同樣的錯誤(幾個小時後),即

GuzzleHttp\Exception\ClientException #400 

Client error response 
[url] http://sandbox.feedly.com/v3/auth/token?code=[auth_code]&client_id=sandbox&client_secret=[secret]&redirect_uri=https%253A%252F%252F[site url]&grant_type=authorization_code&state=%23 
[status code] 400 
[reason phrase] Bad Request 

回答

0

問題:重定向URI是雙重編碼,即我通過https%253A%252F%252Fdev10.ritepush.com%252Fdashboard,它解碼爲https%3A%2F%2Fdev10.ritepush.com%2Fdashboard。我必須對uri進行編碼,這是我需要通過https%3A%2F%2Fdev10.ritepush.com%2Fdashboard

原因: PHP在施加urlencoderedirect_uri編碼的HTTP請求自動所以,我其實編碼重定向URI兩次,但它被解碼一次。因此,編碼URI在請求正文中傳遞,導致錯誤。

感謝大衛Chatenay餵養指出錯誤。

1

從底部開始,按照所述的OAuth 2.0規範:

The client MUST use the HTTP "POST" method when making access token requests.

(來源:部分3.2。 The OAuth 2.0 Authorization Framework

因此這解釋了爲什麼導航到瀏覽器中的請求URL將失敗(導航問題GET,並且只支持POST請求)。

下一點是客戶端身份驗證,更具體地說,您如何提供client_idclient_secret參數,以便服務器可以驗證您是受信任的客戶端應用程序。再次,每規範,有兩種方式該信息應該傳遞:

  1. 通過如[RFC2617],其中客戶機標識符被作爲用戶名和客戶端祕密傳遞定義HTTP基本認證方案作爲傳遞密碼。這種方法必須得到OAuth兼容服務器的支持,並且也是推薦的方式。*
  2. 通過在請求主體中包含客戶端憑證,通常編碼爲application/x-www-form-urlencoded(請參閱下面的示例)。此方法是可選的,可能在某些OAuth服務器中不可用。

    POST https://YOUR_NAMESPACE/oauth/token 
    Content-type: application/x-www-form-urlencoded 
    
    client_id=YOUR_CLIENT_ID 
    &redirect_uri=http://YOUR_APP/callback 
    &client_secret=YOUR_CLIENT_SECRET 
    &code=AUTHORIZATION_CODE 
    &grant_type=authorization_code 
    

    (來源::使在請求體客戶機憑證的

實施例步驟4的OAuth Web Application Protocol,單擊純鏈接在步驟2看到所有在一個完整的授權代碼授權中的原始的HTTP請求流程)

Now,for Feedly用例我找不到任何有關支持HTTP基本認證的文檔。他們說,即將訪問令牌交換代碼所需要的參數如下:

Note: these parameters can either be passed in the URL, as form values, or in a JSON document. If you use a JSON document, make sure you pass the 「Content-Type: application/json」 header in the request.

(來源:Exchanging an auth code for a refresh token and an access token

有一件事是令人驚訝的是,他們似乎允許通過客戶端憑據URL本身,這是東西的OAuth說明書明確規定,禁止:

The parameters (client_id and client_secret) can only be transmitted in the request-body and MUST NOT be included in the request URI.

(源:2.3.1節The OAuth 2.0 Authorization Framework

總而言之,根據他們的文檔,你應該可以做什麼(在URL本身中傳遞參數),除非文檔不是最新的,他們已經修復了不符合規範的要求,並且沒有更長的支持。

此外,有幾件事你做的似乎是錯誤的。 code參數永遠不會在Authorisation標頭中傳遞,因此除非您想嘗試使用基本身份驗證在該標頭中傳遞客戶端憑證,否則我會建議您刪除此標頭。

我也會刪除Accept-Encoding頭,因爲他們的文檔沒有提到支持除返回JSON響應以外的其他任何東西。如果要維護該標題,請將值從gzip更改爲application/json

最後,您也沒有在請求正文中發送任何數據,因此您可能還需要刪除Content-Type標題,因爲Feedly可能認爲如果此標題存在,那麼數據位於請求上而不是URL上。

+0

522狀態碼不是標準的,我知道CloudFare使用它來表示服務器連接超時,所以這可能是Feedly服務器上的問題。請參見[Error-522-Connection-timeoutd-out](https://support.cloudflare.com/hc/en-us/articles/200171906-Error-522-Connection-timed-out)。 –

+0

感謝您的解釋。這很有幫助。我更新了代碼,並得到一個'[status code] 522 [reason phrase] Origin Connection Time-out error'。我在問題中添加了更新的代碼和錯誤。我仔細查看了錯誤的細節,發現它是服務器端錯誤。你能澄清一下錯誤嗎?是否有一些修復(如果我失去了一些東西)我可以從我身邊申請嗎? –

+0

更新後的代碼出現同樣的錯誤:嘗試了幾個小時後,[[status code] 400 [reason phrase] Bad Request']。 522錯誤現在不會提出。你能否解釋一下這個問題? –

相關問題