Gmail search with API and access token - http

I am trying to fetch Gmail search results from Gmail API using an access token.
The following code works and returns an array of my email IDs:
fetch(`https://www.googleapis.com/gmail/v1/users/${userId}/messages?access_token=${accessToken}`)
I then try to append a search query following the Gmail API documentation guidelines
fetch(`https://www.googleapis.com/gmail/v1/users/${userId}/messages?access_token=${accessToken}?q=${text}`)
and it brings this error code: 401, message: 'Invalid Credentials'
Authentication scope is set to https://mail.google.com/ which assumes full control of the email. I tried swapping access_token and q parameters, as well as removing the access_token parameter but still no success. What am I doing wrong?

`https://www.googleapis.com/gmail/v1/users/${userId}/messages?access_token=${accessToken}?q=${text}
you are preforming a HTTP GET in this call. Additional parameters are tacked on using a & only the first one starts with a ?
try this:
`https://www.googleapis.com/gmail/v1/users/${userId}/messages?access_token=${accessToken}&q=${text}

Related

Is it possible to obtain an access_token with expo-auth-session/providers/google?

I am trying to obtain an access token for use with Google APIs using the up-to-date expo-auth-session package.
It works fine to fetch an id_token via useAuthRequest({responseType: "id_token", ...}) or useIdTokenAuthRequest({...})
However, when trying useAuthRequest({responseType: "code", ...}), I get the following error:
[Unhandled promise rejection: Error: The request is missing a required parameter, includes an unsupported parameter value (other than grant type), repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the client, or is otherwise malformed.]
Does anyone know what is missing from the request? I am using the Expo Go app currently, so I'm not sure if that prevents obtaining an access token. Currently digging through the package's source code...
Add the following two props to useAuthRequest
shouldAutoExchangeCode: false,
clientSecret: 'any_bogus_value!'
shouldAutoExchangeCode will prevent the code from being exchanged and send it back to you in the response.
clientSecret will simply trigger and if check to be true in the providers source code that will avoid that error you specified being returned.
Note that in general it is not a good practice to avoid errors, but in this case, I feel like the error is being shown in error itself!

"The provided value for the input parameter 'redirect_uri' is not valid" Using firebase

Firebase tells me to do this:
So I did
But I'm still getting this error "The provided value for the input parameter 'redirect_uri' is not valid"
I feel like I've followed instructions exactly but it's still not working. I have no idea how to debug this further. Any suggestions?
Here is my frontend code where I call signIn
let provider = new firebase.auth.OAuthProvider("microsoft.com");
provider.addScope("Calendars.Read");
firebase.auth().signInWithPopup(provider).then(handleResponse);
Edit
I changed the url to my custom domain and it seemed to be working but now I'm getting Error getting verification code from microsoft.com response: proof key for code exchange is required for cross-origin
For some reason Firebase decided to change the url where it handled auth. Instead of using the .firebaseapp.com/__/auth/handler url, it is using my actual custom domain. Though I don't really understand why this would happen...?
The Error getting verification code from microsoft.com response: proof key for code exchange is required for cross-origin was happening because I had configured an SPA on Azure instead of a Web platform.

How to fix "invalid return_url" error when creating oauth token for Trello with httr?

I want to manage my Trello cards and boards using the trelloR package but when I try to create a token with the get_token function, I get an error message on my browser : "Invalid return_url".
my_token <- get_token(key = my_key, secret = my_secret)
my_key is my personal Trello API key and my_secret is my OAuth secret. I got them on the Trello page that gives you your authentication codes, after login : https://trello.com/app-key
To use the Trello API and to access to boards, I need a token. This token is generated with OAuth1.0 by the httr package. Indeed, the function get_token do something like this, according to Jakub Chromec, author and maintainer of trelloR here :
trello.app = httr::oauth_app(
appname = "trello-app",
key = my_key,
secret = my_secret)
trello.urls = httr::oauth_endpoint(
request = "OAuthGetRequestToken",
authorize ="OAuthAuthorizeToken?scope=read&expiration=30days&name=trello-app",
access = "OAuthGetAccessToken",
base_url = "https://trello.com/1")
httr::oauth1.0_token(
endpoint = trello.urls,
app = trello.app)
When I execute this code or the function get_token with my personal key and secret, I am redirected to my browser, which is normal. As described on this page, a screen should appear asking me to allow authentication. But instead I just have an error message in the browser : "Invalid return_url".
In the RStudio console, this remains displayed :
> my_token <- get_token(my_key, my_secret)
Waiting for authentication in browser...
Press Esc/Ctrl + C to abort
I'm using httr 1.4.1, curl 4.2 and trelloR 0.6.0 with R 3.6.1 under macOS 10.15.
Some people reported the problem started after the introduction of Allowed Origins and they were able to fix it by adding the following origin:
http://localhost:1410
on the appkey page. This is a bit surprising to me as the default * should cover all origins, but there you go.
Trying this today (11/23/2019), I could not get wildcards to work as Allowed Origins. You should specify the domain of where you are running the call for authorization.
One source of confusion: The comments under "Allowed Origins" on https://trello.com/app-key refer to sites that "your application is allowed to redirect back to following the authorization flow." That was a bit confusing to me. The list should include sites you want to redirect back to IN ADDITION TO the sites you are calling Trello.authorize() from.
If you are thinking "I don't need a redirect" (and, in fact, if you are using client.js, I don't think you can specify a redirect), then those comments under "Allowed Origins" could lead you to believe you don't need to specify anything there. That would be incorrect.
Summary: Even if you want NO post-authorization re-direct, you still have to list an ORIGIN.
Also, you cannot specify file:// in Allowed Origins, so you cannot run your javascript off a local file.

"No route found" error with Asana Connect

As per this, I'm trying to use the code received from the authorization endpoint to exchange for a token, using the Authorization Code Grant flow. I first issue this call:
https://app.asana.com/-/oauth_authorize?response_type=code&client_id=123468022031234&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&state=foo
(I admit I don't know how the 'state' param should be used - the documentation doesn't clarify this, and it's required; also, my app is not web-based so the value for the redirect URL is auto-generated on the Developer App Management page for my app)
That gives me this code (slightly obfuscated): 0/12341234fd6ccf6d168420f7f8600c93
Which I then use for this call:
https://app.asana.com/-/oauth_token?grant_type=authorization_code&client_id=123468022031234&client_secret=1234123442d5048f64ac39ca857ec57a&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&code=0%2F12341234fd6ccf6d168420f7f8600c93
Which unfortunately returns "No route found" instead of the token I need. What am I doing wrong?
It has to be a POST. I was using a GET call.

Get refresh token google api

I can't get my refresh token with my code. I can only get my access token, token type etc.,
I have followed some tutorials like putting access_type=offline on my login URL:
echo "<a href='https://accounts.google.com/o/oauth2/auth?"
. "access_type=offline&client_id=123345555.apps.googleusercontent.com& "
. "scope=https://www.googleapis.com/auth/calendar+https://www.googleapis.com/auth/plus.me&response_type=code& "
. "redirect_uri=http://www.sample.com/sample.php&state=/profile'>Google</a>";
and my fields in getting the access token:
$fields=array(
'code'=> urlencode($authcode),
'client_id'=> urlencode($clientid),
'client_secret'=> urlencode($clientsecret),
'redirect_uri'=> urlencode($redirecturi),
'grant_type'=> 'authorization_code',
);
but I can't get refresh_token, just the access_token, token_type, id_token and expires_in.
Found out by adding this to your url parameters
approval_prompt=force
Update:
Use access_type=offline&prompt=consent instead.
approval_prompt=force no longer works
https://github.com/googleapis/oauth2client/issues/453
If I may expand on user987361's answer:
From the offline access portion of the OAuth2.0 docs:
When your application receives a refresh token, it is
important to store that refresh token for future use. If your
application loses the refresh token, it will have to re-prompt the
user for consent before obtaining another refresh token. If you need
to re-prompt the user for consent, include the approval_prompt
parameter in the authorization code request, and set the value to
force.
So, when you have already granted access, subsequent requests for a grant_type of authorization_code will not return the refresh_token, even if access_type was set to offline in the query string of the consent page.
As stated in the quote above, in order to obtain a new refresh_token after already receiving one, you will need to send your user back through the prompt, which you can do by setting approval_prompt to force.
Cheers,
PS This change was announced in a blog post as well.
It is access_type=offline that you want.
This will return the refresh token the first time the user authorises the app. Subsequent calls do not force you to re-approve the app (approval_prompt=force).
See further detail:
https://developers.google.com/accounts/docs/OAuth2WebServer#offline
This is complete code in PHP using google official SDK
$client = new Google_Client();
## some need parameter
$client->setApplicationName('your application name');
$client->setClientId('****************');
$client->setClientSecret('************');
$client->setRedirectUri('http://your.website.tld/complete/url2redirect');
$client->setScopes('https://www.googleapis.com/auth/userinfo.email');
## these two lines is important to get refresh token from google api
$client->setAccessType('offline');
$client->setApprovalPrompt('force'); # this line is important when you revoke permission from your app, it will prompt google approval dialogue box forcefully to user to grant offline access
For our app we had to use both these parameters access_type=offline&prompt=consent.
approval_prompt=force did not work for us
Hi I followed following steps and I had been able to get the refresh token.
Authorization flow has two steps.
Is to obtain the authorization code using https://accounts.google.com/o/oauth2/auth? URL.
For that a post request is sent providing following parameters. 'scope=' + SCOPE + '&client_id=' + CLIENTID + '&redirect_uri=' + REDIRECT + '&response_type=' + TYPE + '&access_type=offline' Providing above will receive a authorization code.
Retrieving AcessToken and RefreshToken using https://accounts.google.com/o/oauth2/token? URL.
For that a post request is sent providing following parameters.
"code" : code,
"client_id" : CID,
"client_secret" : CSECRET,
"redirect_uri" : REDIRECT,
"grant_type" : "authorization_code",
So in your first attempt once you authorize the permissions you will be able to get the Refresh token. Subsequent attempts will not provide the refresh token. If you want the token again the revoke the access in you application.
Hope this will help someone cheers :)
OAuth has two scenarios in real mode.
The normal and default style of access is called online.
In some cases, your application may need to access a Google API when the user is not present,It's offline scenarios .
a refresh token is obtained in offline scenarios during the first authorization code exchange.
So you can get refersh_token is some scenarios ,not all.
you can have the content in https://developers.google.com/identity/protocols/OAuth2WebServer#offline
.
Since March 2016, use prompt=consent to regenerate Google API refresh token.
As mentioned in https://github.com/googleapis/oauth2client/issues/453,
approval_prompt=force has been replaced with prompt=none|consent|select_account
For those using the Google API Client Library for PHP and seeking offline access and refresh tokens beware as of the time of this writing the docs are showing incorrect examples.
currently it's showing:
$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
// offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');
// Using "consent" ensures that your application always receives a refresh token.
// If you are not using offline access, you can omit this.
$client->setApprovalPrompt("consent");
$client->setIncludeGrantedScopes(true); // incremental auth
source: https://developers.google.com/identity/protocols/OAuth2WebServer#offline
All of this works great - except ONE piece
$client->setApprovalPrompt("consent");
After a bit of reasoning I changed this line to the following and EVERYTHING WORKED
$client->setPrompt("consent");
It makes sense since using the HTTP requests it was changed from approval_prompt=force to prompt=consent. So changing the setter method from setApprovalPrompt to setPrompt follows natural convention - BUT IT'S NOT IN THE DOCS!!! That I found at least.

Resources