avoid auth token to expire - authentication

I want to use the gmail api to update myself about the status of a programm I'm running locally 24/7. Basicly once a day it should send me a status report per email from the emailaccount I created just for this case to the same account.
I've got a project set up, the api enabled, got my credentials and created a token.json file. I managed to have it send me emails yada yada yada.
I concentrated on the further development of the programm for some time and then wanted to jump back to this to test out another feature where I wanted to implement a ping me feature. I'd send myself an email asking for a ping back just to check if my program is still running.
While doing that I noticed that my token expired. I tried reading into what I can do about that. Ideally I'd like to have the program just run autonomously. I read for my case that a service account would be ideal but after setting that all up and 2 hours later after a lot of errors I read that interacting with the gmail api with a service account is only open to workspace users since I can't delegate domain-wide authority without one.
So after some further reading I read that next to the access token I created I can refresh that token with refresh tokens. for that I was trying the request function noted in the quickstart tutorial:
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
now running creds.refresh(Request())
I get this error:
google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'})
Upon further reading here I read that refesh tokens are only available to projects whose status is set to in progress and not in testing. Projects set to testing are required to have the user manually log in at least once a week which I don't want.
Now for me verifying my project doesn't make sense since I won't have any other users using my access to the gmail api and frankly I wouldn't want that either.
What are my options here to have the script running continuously without having to manually sign in once a week? Considering also that I will be at all times the only user.
Thank you,
Florens

Your still have a few options. For one, you could get a Google Workspace account. The lowest tier would set you back around $6 per user per month. This would allow you to publish the app as internal-only and you don't need to go through the verification process, but you can only use the app with the Workspace account. You can still send emails out to any addresses, though.
If you don't want to pay, you can still set your app to Published status and you do not necessarily have to go through the verification. There are some limitations, such as the app warning that shows up when signing in and a user cap of 100 users, but since you know that the app is safe and you don't need more users you can just ignore this, Google says so in their own documentation:
What app types are not applicable for verification?
Personal Use: The app is not shared with anyone else or will be used by fewer than 100 users. Hence, you can continue using the app by bypassing the unverified app warning during sign-in.
As you already know, the refresh token expires in 7 days only when the app status is set to "testing", so as long as you have it set as "In production" and ignore the unverified app warnings, you should be able to have a normal refresh token that you can use without needing to sign in every 7 days.
Just keep in mind that other users could have access to the app but if you're careful to keep your OAuth credentials to yourself that should not be an issue.
Sources:
Unverified apps
OAuth API verification FAQs
OAuth overview

Related

OAuth2 Failing at consent stage

I have been happily using the xoauth client to negotiate PKCE grants flows up to earlier today.
Tokens were obtained and refreshed, all was looking fine until I needed to amend my scopes and needed to re-consent.
Now I receive an error on the callback - http://localhost:8080/callback?error=access_denied&state=8AJEDHk6tlNX2E98Y3JuFmXmDrcS2DNB#_=_
This error would usually indicated that consent was canceled by the user but I am definitely pressing Allow.
I have:
Deleted the app and made a new one, tried a new Code Flow app, tried a trial organisation instead of the Demo organisation, all without luck.
However, it will succeed if I specify the bare minimum of scopes: openid and offline_access
Any ideas?
My Client ID is: 17B89D9AF3984680BCA620A3986AE8EB
Update: It does however work in a private browser window so I suspect something local. Will poke some more and close if so.
So that last piece makes it sound like some kind of browser / cache issue.
We did have another user where an ad blocker was causing the problem during the granting access page. Maybe that was you..? API team is looking into this further.
If you are continued to be blocked you can open a ticket by emailing api#xero.com

Expo: WebBrowser.openAuthSessionAsync and related calls skip user input even when browser session expired

This is a summary of an issue I filed directly with expo (it ws closed but I have asked for it to be reopened):
This issue happens whether using AuthSession.startAsync,
AppAuth.authAsync or WebBrowser.openAuthSessionAsync on iOS in
local development and published release (expo managed). Haven't tried
on standalone build yet.
Steps to Reproduce
user presses 'sign in' button, (app calls one of the above methods to kick start authentication session with a Salesforce oauth provider)
user enters credentials successfully
app goes through oauth redirects and returns user to our app and we get our access token.
user presses 'sign out' button (app calls revoke endpoint for token, then calls server endpoint to delete any browser cookie sessions for given account reference)
app navigates to sign in screen
user presses 'sign in' again (app calls the same method from above to start the authentication session with Salesforce oauth provider again)
instead of opening the sign in page, the app redirects itself back with an access token as if the user had successfully entered their credentials, even though any cookies/session data the browser stores should be invalid and necessitate a sign in.
Expected Behaviour
steps 1 - 5 are all as expected. Step six should be
app redirects to Salesforce oauth provider sign in page, in unauthenticated state (ie no cookie or session data that was previously stored is still valid)
user is required to re-enter their credentials
oauth flow takes over and redirects the user into the app if the credentials were correct.
Actual Behavior
as per initial steps where the user is not even asked to enter their credentials (step 6):
instead of opening the sign in page, the app redirects itself back with an access token as if the user had successfully entered their credentials, even though any cookies/session data the browser stores should be invalid and necessitate a sign in.
Reproducible Demo
The code is in a private repo so I can't share details of it, but it's a very standard oauth flow, and seeing it's happening in all three of the method calls from the top suggests to me that it may be due to something in the WebBrowser.openAuthSessionAsync implementation. I have seen on the apple developer docs that SFAuthenticationSession has been deprecated in favour of ASWebAuthenticationSession. My understanding is that this (SFAuthenticationSession) is the browser used by expo's WebBrowser and the wrappers mentioned above (AppAuth and AuthSession) for the oauth interactions. I also see that it mentions it's for a one-time login, which perhaps explains why it would hold onto any session data and jump to the conclusion of re-authenticating without directly seeking credentials from the user, but it seems unhelpful to store a cookie without validating it, which is what appears to be the end result.
Notes
Essentially this is making it impossible for a user to sign out of our app, because the system browser, that we don't have control over, is keeping track of their authentication despite the session value no longer being valid against the server.
I've seen other people looking to find ways to clear cookies from the system browser, which may be what this issue relates to, though it doesn't appear to be possible to access the auth session's browser cookies in any way. This comment on a GitHub issue is exactly what I'm experiencing and need to find a solution to.
I would like users to be able to sign out, and then when they sign back in again they should have to enter their credentials again. Does anyone have any thoughts as to how this might be possible?
On iOS, it's now possible to pass in the following config to WebBrowser.openAuthSessionAsync to essentially treat it as incognito and ensure it doesn't retain any cookies. The effect is that the user will have to re-authenticate each time (even if there session is still active). I'm not aware of a similar approach for Android, however.
Code
const browserOptions = {
preferEphemeralSession: true
}
result = await WebBrowser.openAuthSessionAsync(authUrl, redirect, browserOptions)

Quickbooks API reconnect issue

I've been implementing connectivity to Quickbooks via the v3 API with ColdFusion, and have most everything working except reconnect (https://appcenter.intuit.com/api/v1/connection/reconnect). I can get customer info, create/update invoices, etc, but no luck with reconnect.
From my app I get an Error Code 22 (Authentication required), but I'm sending the same auth header that I send for any of the other API call to access a protected resource. The oauth spec does not specifically have a "reconnect" action so my question is what specific oauth properties need to be included in the auth header for the Quickbooks reconnect call?
From the oauth 1.0 spec is it the headers for Consumer Requests an Access Token?
oauth_consumer_key
oauth_token
oauth_signature_method
oauth_signature
oauth_timestamp
oauth_nonce
oauth_version
oauth_verifier
Or is it the header sent for accessing a protected resource
oauth_consumer_key
oauth_token
oauth_signature_method
oauth_signature:
oauth_timestamp
oauth_nonce
oauth_version
Or, is it some other header set?
Also, I've tried using the Dev Playgorund to test reconnect, and from there I get a
24 - Invalid App Token
So I'm at a loss at this point. For what it's worth Disconnect works fine :)
Any help, guidance, suggestions would be appreciated.
Thanks
The first issue if you are doing things in the order you specify is that you cannot disconnect first and then subsequently reconnect. The reconnect API must be called with a valid access token, as the current access token will be invalidated and a new access token will be issued.
Secondly, there is a window for calling this API to refresh the 6 month life of the access token, it must be called in the last 30 days. This allows your app to refresh the token without prompting the customer again.
However in all cases if you disconnect, or the customer manually disconnects you cannot call the reconnect API. You need to take them through the authorize flow again.
hope that helps
Jarred
To test reconnect from developer playground, use the following steps-
1. Navigate to IPP Playground- Go to Manage My Apps->Click on your app
Fill in consumer key and consumer secret in links below.
Prod: https://appcenter.intuit.com/Playground/OAuth/IA/?ck=<>&cs=<>
Stage: https://appcenter-stage.intuit.com/Playground/OAuth/IA/?ck=<>&cs=<>
Alternatively, you can navigate to the Manage page for your app on stage or prod and click ‘Test connect to app (OAuth)’. Screen shot attached.
2. Enter the duration you would like for the issued OAuth tokens (e.g., 3600 for successful Reconnect) in the ‘Access Token Duration’ field. Screen shot attached.
3. Click on the Connect to QuickBooks button, go through OAuth flow to authorize a connection to a realm.
4. Under the resulting Post-Connection Interactions heading, click ‘Reconnect API Test’. Screen shot attached.
5. A new page will launch where your OAuth tokens are displayed. Copy these values to your application to test Reconnect
As Jarred mentioned that for dev/live apps, there is a window for calling this API to refresh the 6 month life of the access token, it must be called in the last 30 days.
I received this error as well. Error Code 22 (Authentication required) for me meant that the OAuth signature was wrong. This was confusing because I couldn't find this error listed in the Quickbooks documents for reconnect.
I was signing the request as a "POST" request instead of a "GET" request which is what Quickbooks requires for calls to the reconnect endpoint.

How to get user data from Google API with OAuth remotely from a server?

I've been reading lots of documentation about Google API access and OAuth flow using it but I don't seem to get it working in my mind, so I want to get some help first in order to have a clear idea about how it works then I can code it using the corresponding API.
What I want to achieve is feed a Java application running in a PC with specific Google user data, like localization through Google Latitude API. In order to get this, OAuth must be used, so I need getting the user consent, then access the user data from the application running in my computer, and I don't know how to manage this.
I've already registered my application with the Google APIs Console and enabled the Google Latitude module. I've also tried the Latitude console application here and it works properly (a browser tab opened asking for a Google user; I entered it and I got the location data), but I'm having problems when trying to adapt the program flow to my needs.
In my application, the 'remote' user is supposed to send a request (a custom JSON message) to the server asking for service enable/disable, like allowing the server to track his/her position through Latitude. Then, AFAIK, the server should send to the user a URL so the user can give the consent, but I don't know how to get this URL and how the server realizes about this consent and gets the token (automatically? Google tracks this authorization process?). Once my server gets the specific user token, then I should be ready to get service data for that user using the received token.
As I said before, I've tried according to different references, but as the documentation seems to be really scattered and much of it is already deprecated, I've been unable to get it working.
Judging from your description, the installed app OAuth2 flow seems to be the right one for you.
At some point, presumably when a user is installing your desktop app, you should fire up a browser - either embedded one in your app or the default browser - and sent them to this Google OAuth2 endpoint. In your request, fill out all the parameters as required by the doc: Latitude API scope, client_id, etc. Google, as an authorization server, will take care of user authentication, session selection, and user consent. If the user grants access to her data to your API, you will receive an authorization code either in the title of the browser window or at a localhost port.
Once you have the code, you can exchange it for an access token and a refresh token. The access token is what you need to call the API and access the user's data. It is short lived though - check the expired_in parameter in the response, I believe it is 3600 sec. - so you will need to periodically ping the token endpoint with your long lived refresh token and exchange it for an access token.
You can find a more thoroough description of this flow in the doc linked above.

Access tokens expire after only 1 day

With my Flattr client using the REST API, it seems that access tokens expire after 1 day. I checked my settings and the client is still authenticated. But when I issue a request to https://api.flattr.com/rest/v2/user I get the following response:
{
"error":"unauthorized",
"error_description":"You are unauthorized to access the resource",
"error_uri":"http:\/\/developers.flattr.net\/api"
}
I think I now know what the problem is. I am logging into Flattr with an iPhone and with the iPhone Simulator using the same account. It seems that using the API with more than one device will cause the user to need to login every time he changes devices.
I guess support for more than one access token at the same time is needed. Please confirm.