0

我正嘗試創建一個Node.js身份驗證服務以使用Google OAuth API進行身份驗證。嘗試使用Google OAuth進行身份驗證並獲取錯誤「缺少必需的參數:grant_type」

我有這樣的代碼:

private exchangeTokens(code: string): Rx.Observable<IAuthTokens>{ 

    code = decodeURIComponent(code); 

    console.log(`exchanging code for tokens: ${code}`); 

    const redirectUri = "http://localhost:8080"; 

    let url = YouTubeAuthenticationServer.baseUrl + "token"; 

    var postData= "code=" + encodeURIComponent(code); 
    postData += "&redirect_uri=" + encodeURIComponent(redirectUri); 
    postData += "&client_id=" + encodeURIComponent(process.env.CLIENT_ID); 
    postData += "&client_secret=" + encodeURIComponent(process.env.CLIENT_SECRET); 
    postData += "&scope="; 
    postData += "&grant_type=authorization_code"; 

    return this.makePostRequest<IAuthTokens>(url,postData); 
} 

private makePostRequest<T>(targetUrl:string, data: string): Rx.Observable<T>{ 

    console.log(`getting targetUrl: ${targetUrl}`); 

    var urlObject = url.parse(targetUrl); 

    var options: http.RequestOptions = { 
     hostname: urlObject.hostname, 
     port: Number(urlObject.port), 
     path: urlObject.path, 
     protocol: "https:", 
     method: "POST" 
    }; 

    const request = https.request(options); 

    const returnObservable = Rx.Observable.fromEvent(<any>request, "response") 
     .take(1) 
     .flatMap(response => RxNode.fromWritableStream(<any>response)) 
     .do(data => console.log(`data pumped: ${data}`)) 
     .toArray() 
     .map(function(allData){ 
      return JSON.parse(allData.join("")) as T; 
     }); 

    console.log(`write data: ${data}`); 

    request.write(data); 
    request.end(); 

    return returnObservable; 
} 

,並從該我得到以下日誌:

exchanging code for tokens: 4/k6Pp7jCPDms2meo0qfINqs0c9FZSjJ7PvGp8mdnh3Y8# 
getting targetUrl: https://accounts.google.com/o/oauth2/token 
write data: code=4%2Fk6Pp7jCPDms2meo0qfINqs0c9FZSjJ7PvGp8mdnh3Y8%23&redirect_uri=http%3A%2F%2Flocalhost%3A8080&client_id=myCorrectId&client_secret=myCorrectSecret&scope=&grant_type=authorization_code 
data pumped: { 
    "error" : "invalid_request", 
    "error_description" : "Required parameter is missing: grant_type" 
} 

所以我發送以下內容:

code=4%2Fk6Pp7jCPDms2meo0qfINqs0c9FZSjJ7PvGp8mdnh3Y8%23 
redirect_uri=http%3A%2F%2Flocalhost%3A8080 
client_id=myCorrrectId 
client_secret=myCorrectSecret 
scope= 
grant_type=authorization_code 

這樣我就可以」不明白爲什麼它說我不發送grant_type

回答

0

許多許多感謝João Angelo這個答案(貼在下面評論)

確保請求包含這個頭: Content-Type: application/x-www-form-urlencoded 因爲谷歌可以允許其他內容類型和可能被誤解的有效載荷。

現在,該代碼如下所示:

private makePostRequest<T>(targetUrl:string, data: string): Rx.Observable<T>{ 

    console.log(`getting targetUrl: ${targetUrl}`); 

    var urlObject = url.parse(targetUrl); 

    var options: http.RequestOptions = { 
     hostname: urlObject.hostname, 
     port: Number(urlObject.port), 
     path: urlObject.path, 
     protocol: "https:", 
     method: "POST", 
     headers: { 
      "Content-Type": "application/x-www-form-urlencoded" 
     } 
    }; 

    const request = https.request(options); 

    const returnObservable = Rx.Observable.fromEvent(<any>request, "response") 
     .take(1) 
     .flatMap(response => RxNode.fromWritableStream(<any>response)) 
     .do(data => console.log(`data pumped: ${data}`)) 
     .toArray() 
     .map(function(allData){ 
      return JSON.parse(allData.join("")) as T; 
     }); 

    console.log(`write data: ${data}`); 

    request.write(data); 
    request.end(); 

    return returnObservable; 
} 
0

如果您不想指定scope,則不要附加"&scope="。該服務器可以被解釋您的要求爲要求的範圍:

&grant_type=authorization_code 

那麼這將意味着實際上並不包含grant_type請求。

+0

我只加範圍,因爲這正是上對谷歌的OAuth操場的例子過去了。當它被移除時它也不起作用。 – Roaders

+1

還要確保請求包含這個頭文件'Content-Type:application/x-www-form-urlencoded',因爲Google可能允許其他內容類型,並且可能會誤解有效載荷。 –

+0

YESSS !!!!!!謝謝瓊 - 我會加入這個答案並接受它。 – Roaders

相關問題