Cheers everybody,
we have been deeply reading google documentation on exchanging access_token from google in order our (delphi)desktop application to SSO with google from server side. Here is the payload we send first look like:
https://accounts.google.com/o/oauth2/v2/auth?client_id=1000217514248-t1lojs6f8ed7l9ocrpbm98leahtum8n1.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&state=E1DF2FBA-0A66-4D69-B594-5EB8F7828AF7&scope=openid+profile&include_granted_scopes=true&code_challenge=C832DA50-E55A-499D-89B8-493BB4123C94&login_hint=test#Speelkriebel.be
Normally after this it redirects me to login in to our test user and after this according to the documentation we send a POST request to the end point token in order to get the access_token and refresh_token...: 'https://oauth2.googleapis.com/token
with the following parameters, the 'code' is generated we also send it as follow:
client_id=1000217514248-t1lojs6f8ed7l9ocrpbm98leahtum8n1.apps.googleusercontent.com
grant_type=authorization_code
client_secret=******
code= 4/1AY0e-g4GlavO38PI5Oo3vq04Pc4lMWN77et-02UiVWOsT-IyRQnU1lq19qo
redirect_uri = urn:ietf:wg:oauth:2.0:oob
The response is always
{
"error_description": "Missing code verifier.",
"error": "invalid_grant"
}
We have tried to send the client secret id also, Does it have to do with our code_challenge ? are the end points url and initial url okay? What are we missing? We are using CEF4Delphi as "browser like experience in order for the user to type in their google credentials. We have been reading this: https://developers.google.com/identity/protocols/oauth2/web-server#offline
We were also trying the playground :https://developers.google.com/oauthplayground/
we were sending the initial url in a chrome which generated a "code" and in the playground we inserted the code, and still got the same error of missing code verifier.
Thanks Guys
You seam to have URL encoded a lot of the values try not doing that. Also try using the basic call, before you start adding everything else. It should help you figure out which one of those extra parameters you are sending that's causing your issues.
https://accounts.google.com/o/oauth2/auth?client_id={clientid}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=profile&response_type=code
Also make sure that the client id is from an installed / other type client
This may also help Google 3 Legged OAuth2 Flow
For installed apps, the code challenge and verifier are parameters for enhancing the security of the OAuth flow through PKCE [1].
There is additional documentation about generating a code challenge and verifier here [2].
[1] https://www.rfc-editor.org/rfc/rfc7636
[2] https://developers.google.com/identity/protocols/oauth2/native-app#step1-code-verifier
Related
I've successfully implemented Discord's OAuth2 flow using the authorization code grant type into my application. The end user navigates to Discord's OAuth2 link for my bot, authorizes its access, and Discord redirects them back to my site with a code querystring. The bot then exchanges this code for an access token by querying Discord's API. Documentation on this process is available here for reference.
However, roughly every 50-100 requests to the exchange endpoint, I receive a 403 with the error invalid_grant and the description Invalid "code" in request. Frankly, I don't understand how the code just provided by Discord's system is instantly invalid. The same user can complete the process again and no error is returned the second time.
Out of desperation, I tried toggling on the option in the Developers Dashboard named Requires OAuth2 Code Grant seeing that it said "if your application requires multiple scopes," but it made no effect. I've also tried endless debugging, but the circumstances under each occurrence are apparently random. Oddly enough, I can't find anyone with the same issue online.
Below is the request I'm making in Node.js using the superagent library. It matches the documentation and works perfectly, other than the response randomly being the error described.
superagent.post('https://discordapp.com/api/v6/oauth2/token')
.type('x-www-form-urlencoded')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({
client_id: process.env.BOT_ID,
client_secret: process.env.BOT_SECRET,
grant_type: 'authorization_code',
code,
redirect_uri: process.env.OAUTH2_REDIRECT_URI,
scope: 'identify guilds.join',
});
I can confirm that all variables match their expected values. The value of redirect_uri matches that of redirect_uri in the original URL used. code is the value of the code querystring returned through the OAuth2 flow.
What (if anything) am I doing wrong that's causing the error?
Update 1:
Discord has directed me to the API GitHub repo, and I found the issue closed here. Commented and will update here if I receive any helpful info or resolve the issue completely (hopefully the case).
Ran into the same issue using nodejs. Leaving here notes for prosperity:
On Node, if there is no explicit app.head() handler, the .post() handler receives all head requests
Several Android phones, upon being redirected from discord, first send a head request to the endpoint
Meaning:
The user authenticates on discord, then through the redirect back, does a head request. This pulls discord with the code, BUT directly afterwards it also does a post request, which will fail (as you already used the code once), and possibly un-authenticates the user.
Solution for my specific issue was an explicit .head handler for all callback endpoints, which basically just returned the same headers (a redirect) as the post one did, but without calling discord.
Hope this helps.
did you use the OAuth2 link to invite your bot to your server - with the correct permissions? If so, in your main.js file did you define the token?
I.e. bot.login(“YOUR_TOKEN_HERE”)
I would recommend not toggling the ‘Requires OAuth2 Code Grant’ as it is a pain to do anything with in the beginning.
Please let me know of any progress :)
As part of the OpenID Connect (OAuth2 for Login), my application is supposed to request an access token, given a one-time authorization code, via the endpoint https://www.googleapis.com/oauth2/v3/token. According to documentation, this request needs 5 parameters passed to it, client_id among them. That is exactly what my application does, using the Perl module Net::OAuth2.
Everything has been working fine for several months, but today I was notified that it stopped working. No updates were made to the application code nor the libraries used by it.
The message my application now receives from the server when calling the token endpoint is this, in a 400 error response:
OAuth 2 parameters can only have a single value: client_id
A Google search suggests nobody has ever seen this message before, or lived to tell the tale. There doesn't seem to be a general issue with Google's OpenID Connect (other services based on it are working flawlessly), and the imminent shutdown of the old login protocol doesn't seem relevant.
More testing: removing all parameters except client_id causes this error message:
Required parameter is missing: grant_type
Supplying only client_id and grant_type produces the original error message again.
Does anyone have an idea what's going on here?
Google changed this behavior few days ago, so any OAuth2 library using Basic Auth headers AND body request parameters will start to see messages like
OAuth 2 parameters can only have a single value: client_id
or
OAuth 2 parameters can only have a single value: client_secret
So, you must now do NOT use both (the Auth headers and body request parameters) at the same time to send credentials to Google.
And according RFC 6749, the preferable way to send credentials is through Auth headers (thanks #JanKrüger for alert me about this).
Got the same error. It seems the problem is that NET::OAuth2 sets the authorization header when exchanging authorization code for access token. If you remove this header everything works fine.
Check the get_access_token method in Net::OAuth2::Profile::WebServer module. The authorization header includes client_id:client_secret base64-encoded string. Apparently Google now treats this duplication as an error.
The right way of fixing this is to set the secrets_in_params parameter when creating Net::OAuth2::Profile::WebServer object. Look in the Net::OAuth2::Profile documentation for more details.
I'm trying to get request_token from https://api.twitter.com/oauth/request_token. But I always got following error.
"Failed to validate oauth signature and token"
Below is my signature_base:
POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_callback%3Dhttp%3A%2F%2Fwww.google.com%26oauth_consumer_key%3DydxYUl45Mleo5LNyoExnAF4mY%26oauth_nonce%3D9C918901-EF8A-4B84-BDF5-B7E754C46397%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1415174195%26oauth_version%3D1.0
The auth header generated is:
{
Authorization = "OAuth oauth_version=\"1.0\",
oauth_nonce=\"9C918901-EF8A-4B84-BDF5-B7E754C46397\",
oauth_signature_method=\"HMAC-SHA1\",
oauth_consumer_key=\"ydxYUl45Mleo5LNyoExnAF4mY\",
oauth_timestamp=\"1415174195\",
oauth_callback=\"http://www.google.com\",
oauth_signature=\"j6k3CY4Fr40SKAWiG%2B5%2BwkErdYc%3D\"";
}
I verified the signature with my secret key and it's correct. Really can't figure out where the problem is...
One clue is that when oauth_callback is not used at all, I'm able to get request token... Please help!
Thanks,
Lee
Edit:
If I don't use oauth_callback, I'm able to get request token and the callback I set in dev twitter website is used. However, I can't set it to URL Scheme of my app since it's not valid url...
You are not encoding the oauth_callback url correctly.
In the signature base it should be encoded as:
oauth_callback%3Dhttp%253A%252F%252Fwww.google.com
and then in the Authorization header as:
oauth_callback="http%3A%2F%2Fwww.google.com"
The same problem i was struggling as well.
Approach that help is bellow.
Using Twitter to authenticate is quite uncomfortable to do due to the errors and bad documentation. I will defiantly recommend you, to use one of the two approaches that are : Github library that is well documented and easy to implement. Or use iOS Social framework to write own logging.
I have been trying with the simple REST Client as well as the REST Plugin for Mozilla. I am getting
"HTTP/1.1 401 Unauthorized" response with
"{"error":"unauthorized_client","error_description":"the client is not authorized"}" in the body.
I have been successful in getting the auth code, and the below is the POST request for access token, (Scope is r_fullprofile)
https://www.linkedin.com/uas/oauth2/accessToken?grant_type=authorization_code&code=AQTQeBxBzbU2aNWaQM6Ff3Z3bUd8Gyg10W9G2DdqXgWiP0q7-M55c5PLtppP7Ni3Y-6A9C8yDkj9K4VfJ7QkRUFjuV-3AknA5jAahpsFJv3wYfr8XD8&redirect_uri=https://www.google.com&client_id=75wl6j5zndvfkp&client_secret=secret
The redirect_uri=https://www.google.com is the one used for getting auth code as well.
Do we need to perform any URL encoding before making the POST request?
When I log into the linked in to my app, it has the below tokens,
OAuth User Token: c3ae4cee-1b23-xxx-9d2a-206f578dee4d
OAuth User Secret: 76bc48cc-c94f-xxx-bf9d-a663f7003383
I am not sure where it is used. we are using API & secret key to get auth code.
Thanks in Advance.
This is a 2-step process.
First, go to:
https://www.linkedin.com/uas/oauth2/authorization?response_type=code&client_id=YOUR-API-ID&scope=r_basicprofile&state=STATE&redirect_uri=YOUR-ENCODED-REDIRECT-URI
Then, within 10 secs of receiving the response, go to:
https://www.linkedin.com/uas/oauth2/accessToken?grant_type=authorization_code&redirect_uri=YOUR-ENCODED-REDIRECT-URI&client_id=YOUR-API-ID&client_secret=YOUR-API-ID&code=THE-CODE-OBTAINED-IN-FIRST-STEP
The response of the second request will have the actual access token you need to use.
When I followed the two steps I faced an issue where I got an error as
{"errorCode":0,"message":"Access to posting shares denied","requestId":"TYWULO2WPZ","status":403,"timestamp":1497353538016}
So I had to remove the &scope=r_basicprofile since it was preventing reading all the Default Application Permissions
I faced a similar problem and the problem was with the initial authorization code. You should mention the scope=rw_company_admin or whatever it is that you want to authorize to while doing the initial redirect URL call. Something like this -
https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=your_client_id&redirect_uri=https%3A%2F%2Fwww.google.com/&state=12345&scope=rw_company_admin%20r_emailaddress%20w_share%20r_basicprofile
I know same question has been asked many times but even after following each and every post as well trying various suggestions, I am still facing invalid_request error.
I am able to get code successfully from Google API and when I am trying to access accessToken , I am getting this error and HTTP code being sent from Google API is 400.
I have already tried and compared my data with oauthplayground and seems everything is same
Following data is being sent from my Application to Google API
https://accounts.google.com/o/oauth2/auth?
scope=openid+profile+email
&response_type=code
&redirect_uri=http%3A%2F%2Fsavealifetoday.org%2Fblood_donors%2FoAuthCallBackAction%3Fservice_provider_name%3D
&approval_prompt=force
&client_id=193214746340-ea0nq5alpst82n2fno13s9j21pn4f4pf.apps.googleusercontent.com
Access Token URL
https://accounts.google.com/o/oauth2/token?
scope=openid+profile+email
&client_secret=***********
&grant_type=authorization_code
&redirect_uri=http%3A%2F%2Fsavealifetoday.org%2Fblood_donors%2FoAuthCallBackAction%3Fservice_provider_name%3D
&code=4%2F8veoAnihzkao58oWvZaRShn5nhYg.0to7Or-lHPwRXE-sT2ZLcbTblHXFhgI
&client_id=193214746340-ea0nq5alpst82n2fno13s9j21pn4f4pf.apps.googleusercontent.com
But When Application is trying to fetch data over the network, I am getting exception
SEVERE: Error while fetching access token for Google..
OAuthProblemException{error='invalid_request', description='null', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}
I am using URLConnectionClient to establish network connection
Go through the OAuth flow using the OAuth playground https://developers.google.com/oauthplayground/.
Then compare what is being sent with your own.
Note that it needs to be an HTTP POST. The code you posted looks like a GET.
Also, your redirect URL looks a little odd. Is that exactly the same URL that you registered in the API console? This is isn't your current error, but will probably become your next one ;-)
It seems that you forgot to send 'state' parameter here (it is mandatory!):
https://accounts.google.com/o/oauth2/auth?
scope=openid+profile+email
&response_type=code
&redirect_uri=http%3A%2F%2Fsavealifetoday.org%2Fblood_donors%2FoAuthCallBackAction%3Fservice_provider_name%3D
&approval_prompt=force
&client_id=193214746340-ea0nq5alpst82n2fno13s9j21pn4f4pf.apps.googleusercontent.com
In Java code you can generate it in a way like this:
String state = new BigInteger(130, new SecureRandom()).toString(32);
So you request should look like this:
https://accounts.google.com/o/oauth2/auth?
scope=openid+profile+email
&response_type=code
&redirect_uri=http%3A%2F%2Fsavealifetoday.org%2Fblood_donors%2FoAuthCallBackAction%3Fservice_provider_name%3D
&approval_prompt=force
&client_id=193214746340-ea0nq5alpst82n2fno13s9j21pn4f4pf.apps.googleusercontent.com
&state= {insert_here_generated_state}
And also I don't know if it is necessary to send a 'scope' parameter in "Access Token URL".