Google OAuth 2 authorization - swapping code for token - oauth-2.0

I'm trying to implement Google OAuth 2 to get access to Google APIs. I follow this guide, using server-side scenario.
I have no problem with getting the code, server redirects to localhost (which is the only server allowed in redirect URIs for now).
To achieve this, I go to https://accounts.google.com/o/oauth2/auth?client_id=whatever.apps.googleusercontent.com&redirect_uri=http://localhost/&scope=https://www.google.com/m8/feeds/&response_type=code page.
Then, I tried using curl (as in guide) to test, if Google's server responds with access token. However, it seems to fail very hard. Only response I can get is {"error":"invalid_client"}. I'm sure I provide everything Google wants me to provide - code, client ID, client secret, redirect URI (localhost) and grant_type=authorization_code.
Whole curl command line is:
curl https://accounts.google.com/o/oauth2/token -d "code=<code>&client_id=whatever.apps.googleusercontent.com&client_secret=<won't tell!>&redirect_uri=http://localhost&grant_type=authorization_code"
Am I missing something? How can I exchange code for access token?

Did you urlencode your client secret and redirect url? That works for me.
Should be http%3A%2F%2Flocalhost instead of https://localhost.

I had the same error until I realized that I was trying to connect with a client ID which I created for iOS. So for me the solution was to create a new API key-secret pair on the API Console with the platform set to "other".
Now I'm getting other errors but that's another story. ;)

Happens when you use wrong Client secret. Make sure you are using correct Client secret from Google API console. I was using Email address since API console displays the information in the following order:
Client ID
Email address
Client secret

Related

Find out who invited my bot the server using OAuth redirect uri

Before someone marks this question as duplicate,
Yes I know audit log is a thing.
No I won't use it because it requires permission.
Yes it's easier to find out server owner
No I need to know exactly who invited my bot
I want to:
Find out who invited my bot the server (user-guild id pair) using invite link redirection.
I read about the OAuth2 API but didn't quite undertstand it due to my lack of background knowledge.
All I understand is that bot invite links can have redirect uri,
and some infos are transfered to it after authentication.
Is it possible to get user/guild id from this?
I tried:
Setting up http server using python -m http.server,
add my IP to redirect uri list in dev page & generate a invite link containing redirect to my IP.
But I didn't get redirected to my http server after inviting my bot using that link,
and nothing got printed on the http server console either.
Things to note:
A. Don't reveal your client secret or your bot token for any purpose. If you do so, immediately regenerate them from the developer portal.
B. Code and token have different meanings in the answer below.
C. This is not for absolute beginners and you are expected to have a general understanding of web requests(specifically GET and POST requests). You might also need to host the site handling redirect URL.
D. This does not cover security issues in any shape, way or form.
In the bot tab of the developer portal, enable the REQUIRES OAUTH2 CODE GRANT option. This prevents the bot from joining a server unless step 4 is completed.
Then use the OAuth tab to generate an OAuth URL with identity and bot scopes. This is important to get user info in step 5.
When someone visits the URL, logs in, and selects a server, they are redirected to your redirect URL. This URL receives a single-use code as URL parameter ie the URL will be <base_url>&code={code}<other stuff>. It is up to you (and probably outside the scope of any SO answer; google is your friend here) to set up a web server and handle requests.
This code can then be used to get a token. This link explains how to exchange code for token. It involves sending a post request with your application's client id and secret. Both are available from discord's developer portal. The response will also have information about the guild along with the token in fields "guilds" and "access_token" respectively.
Send a get request to https://discord.com/api/v9/users/#me with a header containing Authorization: Bearer ${token} where the token is obtained in step 4. The response is in JSON format and contains user data specified here. Note: The link above is for the latest API version v9 which may change in future versions.
Edit:
It is possible to manually modify the URL to remove identity scope from URL. The bot would still join the server as long as you make a request to exchange the code for the token. In this case, the request to /users/#me would fail and you would have no access to the user object. It should be easy to make the bot leave the server if the request fails with the status code corresponding to unauthorized.

Problem with Token URL for Basecamp 3 API

I am building an oauth app to connect to Basecamp 3 API using PHP and following the documentation here.
https://github.com/basecamp/api/blob/master/sections/authentication.md
The request authorization url works fine
https://launchpad.37signals.com/authorization/new
but the token url produces a page not found
https://launchpad.37signals.com/authorization/token
I contacted Basecamp but didn't get a response. They do say they don't prioritize suppose issues with the API because so few of their customers use it.
Any ideas on what the correct url for getting tokens would be?
There are 4 steps:
Step 1: Choose a webhook service or build your own (which certainly takes more time). This will receive the authentication.
Step 2: Register your app within Basecamp. it'll give you the client key and secret key
Step 3: You need to make a GET call to the .../new address. You need to pass on the client key, secret key and redirect url. The API will send an 8-digit number to the Webhook. You need to retrieve that from the webhook.
Step 4: Make the same GET call to the .../token address. You'll pass the key in addition to all previous information in the header. Then you'll receive an access token.
Supposedly with this access token you should be able to activate all other API. I have not figure this part out.

WSO2 API Manager with third party key manager returns a token which expires immediately

I am using WSO2 APIM 2.1.0. I followed this guide, I managed to make everything work but at the last step to generate an access token in order to call my API, I'm facing an issue. I make the call to get my token :
curl -k -d "grant_type=client_credentials&scope=test" -H "Authorization: Basic <base64id+secret>, Content-Type: application/x-www-form-urlencoded" http://localhost:8080/v1/token
I actually get my token
{"scope":"test","access_token":"67d45764-a4d3-4467-a0cc-67df34e53b28","token_type":"bearer","expires_in":3600}
But then I try to use it to call my api I get the following error :
Access failure for API: /api/1, version: 1 status: (900901) - Invalid Credentials. Make sure you have given the correct access token
When I directly check the WSO2 APIM Store interface I don't see an access token. Plus if I try to generate it from the interface it works, I get an access token which doesn't work as well and if I reload my page it disappears. I'm obviously doing something wrong but I can't figure out what. Is there some configuration that's not specified in the guide mentioned above ?
I have modified the endpoint in TokenAPI.xml with http://127.0.0.1:8080/v1/token, but I don't know what the revoke endpoint is.
The WSO2 APIM Store is only for testing purposes. The tokens generated via the curl are totally separate from the Store interface.
In your case, please check the api scopes are set correctly. (As you genereate a token with scope 'test', the api should also have the test scope)
I had an Identity Server running as well and didn't think to check the configuration. I had to uncomment the APIKeyManager section of the api-manager.xml in the Identity Server. I don't understand why having only one configuration setup gives you a token but not the correct one, it should not give you a token or throw an error saying that configuration is missing in the IS or something.

Thinktecture Authorization Server TokenRequestValidator returns 'Anonymous Client'

I have an interesting problem. We have set up the Thinktecture Authorization Server from the trusty Identity Server 2 and gotten it to work a few months back. It is configured as a relying party for an already existing corporate identity server, so when we use the Code Flow example, click the "Start authorization handshake" we bounce over to the identity server, supply our credentials and get bounced back to the callback of the code flow with an access code, click the Get Token, and are granted with this fine jwt token. All seems fine.
However,
When we try this either from, for instance, postman, or our app development team from their development devices (android and iphone), it starts fine but when we call the token endpoint with our newly minted access code we get an "Anonymous client" response.
Looking at the web example from the CodeFlow example I see it posts basic authentication including a base64 value of the secret wich is missing from postman and our app team. I see no reference to this in the CodeFlow example so I have no idea where this comes from. If I hard code the Authorization BASIC [including the Base64 secret I snatched from the previous example] it does not change anything.
We'be been stuck for several days on this so any help would be gratefully appreciated. Any Ideas?
After a lot of recearch and hair pulling it seems the Postman client we are using does not support Code Flow and therefore does not include the Authorisation header we are missing. After capturing the traffic from Postman with Fiddler we manually added the basic authorization header with the client name and secret and got everything working. So as of now, postman does not work.
I hope postman does add support for codeflow in the future.
Atli

Google OAuth2 Authorizing OAuth token error: redirect_uri_mismatch

I am Creating and Authorizing an OAuth Token according to this webpage: https://code.google.com/p/google-mail-oauth2-tools/wiki/OAuth2DotPyRunThrough
But I got this error: redirect_uri_mismatch.
The redirect URI in the request: urn:ietf:wg:oauth:2.0:oob did not match a registered redirect URI
from_login=1
cookie_policy_enforce=false
scope=https://mail.google.com/
response_type=code
access_type=online
redirect_uri=urn:ietf:wg:oauth:2.0:oob
as=-80019291b2cb8ed
display=page
pli=1
client_id=......
authuser=0
hl=en
I thought this might be helpful: Google OAuth 2 authorization - Error: redirect_uri_mismatch
But when I try to register the redirect url to my console, I was told that the url is invalid.
The redirect_uri (urn:ietf:wg:oauth:2.0:oob) is only applicable to those Google client ids that have been generated for installed applications. You can go to your console and create a new client id of this type.
Just in case if you're using Google+ javascript button (with web application), you have to put postmessage instead of actual URI. It takes me almost whole day to figure out this, because Google docs doesn't clearly stand it for some reason.
For my web application i corrected my mistake by writing
instead of : http://localhost:11472/authorize/
type : http://localhost/authorize/
When you register your app at https://code.google.com/apis/console and
make a Client ID, you get a chance to specify one or more redirect
URIs. The value of the redirect_uri parameter on your auth URI has to
match one of them exactly.
Please note that the 'redirect_uri' value of the Token request need to be the same as the 'redirect_uri' value of the Authorization request.
Lost 4 or 5 hours with this... use 'postmessage' as parameter value, not the real Redirect Uri...
$client->setRedirectUri('postmessage');
For anybody that is still stumped with this problem, you must have the 'Platform' set to 'Native (Windows Mobile, Blackberry, desktop, devices, and more)' when registering your app in the Google Cloud Console, otherwise, it will not let you use 'urn:ietf:wg:oauth:2.0:oob' as the redirect URI.
In my case, instead of creating web app, i just chose Other in:
OAuth Client ID > Other
and thats it.
2015July15 - working signin started causing Error 400 with Error: redirect_uri_mismatch
i posted a solution on a similar SO QUESTION: changed loading script to
<script src="https://apis.google.com/js/client:platform.js?onload=startApp></script>
For my native app, I tried dozens of different things. I finally got it to work by using "redirect_uri=http%3A%2F%2Flocalhost%3A1234" where 1234 is the port number. This has to be identical in the two requests (authorization code and the access token). Notice the use of percent encoding.
I was getting this error, because I was incorrectly following the steps for installed application flow here
https://github.com/googleads/googleads-python-lib/wiki
instead of the server to server flow.
The easiest way is to create the service account.
Create the document using your own account and share it with the service account.
redirect_uri must be an EXACT MATCH on the developers console.
In my case, this was due to a trailing slash( / ).
In the Google Cloud console, I had http://localhost:8080 under the redirect URIs in the list while my code was sending http://localhost:8080/ while making the oAuth call.

Resources