2013-11-20 67 views
0

我試圖刷新訪問令牌使用Youtube API v2與C#。我做這樣的:Youtube API刷新令牌與C#返回invalid_grant

string _url = "client_id=" + HttpUtility.UrlEncode(_clientID) + "&client_secret=" + HttpUtility.UrlEncode(_clientSecret) + "&refresh_token=" + HttpUtility.UrlEncode(_refreshToken) + "&grant_type=refresh_token"; 

public string RefreshYoutubeToken(string _url) { 
    string _response = ""; 
    TcpClient _tcpClient = new TcpClient("accounts.google.com", 443); 
    Stream _netStream = _tcpClient.GetStream(); 
    SslStream _sslStream = new SslStream(_netStream); 
    _sslStream.AuthenticateAsClient("accounts.google.com"); 
    { 
     byte[] _contentAsBytes = Encoding.ASCII.GetBytes(_url.ToString()); 

     StringBuilder _message = new StringBuilder(); 
     _message.AppendLine("POST /o/oauth2/token HTTP/1.1"); 
     _message.AppendLine("Host: accounts.google.com"); 
     _message.AppendLine("Content-Type: application/x-www-form-urlencoded"); 
     _message.AppendLine("Content-Length: " + _contentAsBytes.Length.ToString()); 
     _message.AppendLine(""); 

     byte[] _headerAsBytes = Encoding.ASCII.GetBytes(_message.ToString()); 
     _sslStream.Write(_headerAsBytes); 
     _sslStream.Write(_contentAsBytes); 
    } 

    StreamReader _reader = new StreamReader(_sslStream); 
    while(true) { // Print the response line by line to the debug stream for inspection. 
     string _line = _reader.ReadLine(); 
     if(_line == null) { break; } 
     _response += _line; 
     if(_line == "0") { break; } 
    } 
    return _response; 
} 

這工作得很好,當我登錄和檢索access token首次,然而,當我想用​​refresh token來獲取新的access token,就像他們在Google Developers上描述 - https://developers.google.com/youtube/2.0/developers_guide_protocol_oauth2#OAuth2_Refreshing_a_Token - 我收到一個錯誤,返回invalid_grant

我讀somwhere,問題可能來自不同的客戶端 - 服務器日期時間,我的結論是,其實我的客戶日期比服務器後期約3秒,例如,客戶端12點10分52秒和服務器12:10:55。
我已經試過改變客戶的日期時間,但沒有運氣。

有沒有人有任何想法如何解決這個問題?使用這種方法或其他方法,我只需要刷新access token

+0

查看底層的http post請求並將其與oauth操場進行比較。最有可能的原因是您的網址或發佈數據有誤 – pinoyyid

+0

@pinoyyid我搞砸了,得到了這個結果:'POST/o/oauth2/token HTTP/1.1 主持人:accounts.google.com 內容長度:211 內容類型:應用/ X WWW的窗體-urlencoded 授權:承載 CLIENT_ID = XXXXXXXXXXX& client_secret = XXXXXXXXXXX& refresh_token = XXXXXXXXXXX& grant_type = refresh_token'然而它返回無效的請求。它與此相同:http://goo.gl/FEIwj但它不起作用。當你用xxxxxxx輸出你正在屏蔽該問題的代碼時,你需要輸入 –

+0

。只需更改一些隨機數字即可。我懷疑這裏有人對你的Youtube視頻感興趣。見下面 – pinoyyid

回答

0

確保您URL編碼每個表單參數,而不只是它們附加到_url - 我認爲有以下幫助:http://msdn.microsoft.com/en-us/library/4fkewx0t(v=vs.110).aspx

此外請確保您通過刷新令牌(而不是訪問令牌或授權碼)。不能保證改變,但目前通常以「1 /」開頭。

+0

我已經這樣做了,如果我編碼'_url'首先返回錯誤從'invalid_grant'變爲'invalid_request'。鑑於我能夠建立第一個連接,而不會導致網址,我想我不需要在這裏做,無論哪種方式,都不工作。關於'refresh_token',我使用的是正確的,它確實以「1 /」開頭。 –

+0

我並不是要編碼整個_url,而是編碼構成它的每個參數。即:_url =「client_id =」+ urlencode(client_id)+「&...」。你能確認這是你已經在做什麼嗎? (在你的評論中並不清楚) – aeijdenberg

+0

我實際上編碼了整個'_url',因此'invalid_request'返回。但是,即使我編碼每個參數,返回錯誤仍然是'invalid_grant'。 –

0

作爲@aeijdenberg,我懷疑你不正確urlencoding每個參數。請記住我的建議是去Oauth遊樂場看看它發送了什麼。 (該文檔不URI編碼被誤導PARAMS)

因此,這裏是你的要求應該是什麼樣子

POST /o/oauth2/token HTTP/1.1 
Host: accounts.google.com 
Content-length: 163 
content-type: application/x-www-form-urlencoded 
user-agent: google-oauth-playground 

client_secret=************&grant_type=refresh_token&refresh_token=1%2Fz5Ogwmp8TqDL31eU1L_Nhddiva_L_8tR7V9k&client_id=407408718192.apps.googleusercontent.com 

如果且僅當,你的要求是完全一樣的,因爲這和你仍然無效的授權,那麼你的刷新令牌有問題,所以得到一個新的令牌。

+0

我的請求與您的請求完全相同,並且它在OAuth操場中返回'invalid_grant'。我已經嘗試了一個新的'refresh_token',並且發生了同樣的事情。這是事實,我的'access_token'仍然有效,但我已經嘗試過,在令牌過期之前和之後它總是返回'invalid_grant'。在API服務中,我有BigQuery,Freebase,YouTube Analytics和Youtube數據API,我是否缺少任何服務? –

+0

我用我的問題製作了OAuthPlayground的屏幕截圖,你能告訴我這裏有什麼問題嗎?[截圖](http://oi40.tinypic.com/ab4ebd.jpg)。我做的另一件事是,我刪除了用戶Google帳戶中的應用權限,並再次給他們提供了另一個身份驗證,但這並未解決問題。 –

相關問題