Google API - request for token from Oauth2 returns

2019-04-06 21:28发布

问题:

I am trying to make an app using Google's calendar API. I'm following the directions here. I can make the request to get the authorization code, but I can not seem to form a valid request to get an access token. I keep getting the response {"error" : "invalid_request"}. This is the POST request I am making:

POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded

code=4/vxQqw9JMYEnXvI8A_93OV7kBSg6h.8r2yJUkMc18dshQV0ieZDAraZNwsbwI&
client_id=[my client id]&
client_secret=[my client secret]&
redirect_uri=http://localhost:8080/auth&
grant_type=authorization_code

Below is the output from calling the url through curl. My actual app is written in Node.js, but I get the same response from curl as I do through the app. I've searched around and seen people with similar problems, but still can't figure out what I'm doing wrong.

curl -v -k --header "Content-Type: application/x-www-form-urlencoded" --data-urlencode "code=4/vxQqw9JMYEnXvI8A_93OV7kBSg6h.8r2yJUkMc18dshQV0ieZDAraZNwsbwI&client_id=[my client id]&client_secret=[my client secret]&redirect_uri=http://localhost:8080/auth&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token
* About to connect() to accounts.google.com port 443 (#0)
*   Trying 173.194.74.84... connected
* Connected to accounts.google.com (173.194.74.84) port 443 (#0)
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using RC4-SHA
* Server certificate:
*    subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=accounts.google.com
*    start date: 2011-07-21 00:00:00 GMT
*    expire date: 2013-07-18 23:59:59 GMT
*    common name: accounts.google.com (matched)
*    issuer: C=ZA; O=Thawte Consulting (Pty) Ltd.; CN=Thawte SGC CA
*    SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
> POST /o/oauth2/token HTTP/1.1
> User-Agent: curl/7.21.3 (i386-apple-darwin8.11.1) libcurl/7.21.3 OpenSSL/0.9.7l zlib/1.2.5 libidn/1.17
> Host: accounts.google.com
> Accept: */*
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 180
> 
< HTTP/1.1 400 Bad Request
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: Fri, 01 Jan 1990 00:00:00 GMT
< Date: Tue, 29 May 2012 12:43:49 GMT
< Content-Type: application/json
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< Server: GSE
< Transfer-Encoding: chunked
< 
{
  "error" : "invalid_request"
* Connection #0 to host accounts.google.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
}

回答1:

Request body should be in single line like this:

code=4/vxQqw9JMYEnXvI8A_93OV7kBSg6h.8r2yJUkMc18dshQV0ieZDAraZNwsbwI&client_id=[my client id]&
client_secret=[my client secret]&redirect_uri=http://localhost:8080/auth&grant_type=authorization_code


回答2:

You did not URL encode your post request. I can tell by

 redirect_uri=http://localhost:8080/auth

not having the %99 for the colons and slashes. I had the same problem with wget. I thought it would URL encode it for me, but it would not. Also, in your custom POST, you can't have newlines between the ampersand and the next form post value. It has to be all on one line. That was also my problem with wget.