how to count app online users and statistic user online time - oauth

I designed a mobile app with a server side. The user is authorizated by OAuth, but how can I count the online users realtime, and how to statistic how long the user keep online.
After the user request an access token, every time the user access other resource in server should take this token, and the server side does not keep the access token. The access token has a long life time. So how should I design the sytem to make it can count the online users and the user online time.

Related

Xero API Token Handling

We think we have a challenge with Xero tokens possibly due to how store and retreive the access and refresh token.
We have an application that seems to disconnect some tenants/Xero Organizations from time to time. We are currently storing a single token (and using refresh and access tokens) without issue, but it feels like when a different user then authorizes a new tenant within our partner organziation, some of the previously authorized tenants stop working.
Do we need to maintain a new set of tokens per user who authorized the request? E.g. User A has a set of Access+Refresh Tokens and User B has a set of Access + Refresh tokens? If so, how do we keep track of what user has authorized which organization last? E.g. if User A authorized Org1 and User B authorized Org2, but then User A also authorized Org2, when our app (per schedule) needs to access Org2 do we just have to enumerate all the tokens and call GetOrganizations() to determine which ones they have?
Again, we have been operating on the idea that a single Access + Refresh token is all we should work with despite working with 100's of tenants/Organizations.
Any great advice on the proper way to store and re-use tokens for Xero would be really appreciated.
We used to store tokens separately, but the combined into single token as it seemed correct, but we still seem to have a few issues, not sure if we need to store a token per user (e.g. decrypt the Access Token, the get User ID, and store 1 pair per unique user id (access+refresh). Is this the proper way so that we don't have disconnect all the time?
Access tokens are issued per user per app. So user A would have one token pair for all the Xero organisations that they have authorised with your app and user B would have another pair for the organisations that they have authorised.
Storing 1 pair per user id would be a good idea.

Quickbooks: Authentication and authorization without human interaction

Can anyone provide a way to get the access token & refresh token without human interaction?
I've one account with which I have to make all the requests to quickbooks and don't want all my application users to provide quickbooks credentials.
It sounds like you're probably misunderstanding how OAuth works, specifically in the context of how Intuit wants it's customers to securely grant you access to QuickBooks data.
For each company who wants to connect your app to QuickBooks, you'll need human interaction to occur just once, and only once. This is not optional. It is mandatory. Human interaction is required one single time, and then after that you can exchange data with QuickBooks whenever you want, without any further interaction with a human.
Your application users will never provide QuickBooks credentials to you directly (e.g. you should not be collecting QuickBooks passwords or usernames).
Build your app to support OAuth2:
https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/oauth-2.0
For each QuickBooks company (not each user, but each company) that you want to exchange data with, have one user auth via OAuth, just once.
You'll receive an access_token and a refresh_token. Save those in your database.
Once you save those, you never have to have a human interaction again for that connected company.
Use those tokens to make calls to QuickBooks. When the access token expires, use the refresh token to get a new access and refresh token. Save both new tokens to your database. Use those to make calls in the future. Repeat.

How long does the connection to Google Calendar API lasts?

I am building a website where the users can schedule a meeting between two persons. In this meeting, there will also be a third person that will ALWAYS be the same and always be there.
My idea was, on the admin panel, make this third user logout and when there is a request for a meeting in the app, make a calendar event / Google Meet where the third account will invite the two users.
This action will be made automatically and these events will happen on the span of many months. I wanted to know how often the user will have to connect. Can he connect just once and then the token for the requests is valid forever or will the third attendee have to login periodically in order to keep the token "fresh"?
Thanks!
The way oauth works is that when authorized you are granted an access token which will give you access to the users data for one hour. If when authorizing the user you request "offline" access as well then you will be given a refresh token.
The refresh token does not expire for the most part, and can be used to request a new access token at anytime. There by refreshing your access as needed.
Get a refresh token for this user and then just refresh the access as needed.

Google OAuth 2.0 offline access

My app needs to access user's data even when the user is not present. So my request for authorization code includes access_type=offline meaning I will get back a refresh token if this is the first time the user authenticates my app. I save the refresh token and use it later on.
Everything works as expected and pretty well. But what bothers me is a statement in the documentation:
Note that there are limits on the number of refresh tokens that will
be issued; one limit per client/user combination, and another per use across all clients. You should save refresh tokens in long-term
storage and continue to use them as long as they remain valid. If your
application requests too many refresh tokens, it may run into these
limits, in which case older refresh tokens will stop working.
If I understand this correctly, it is possible the refresh token I save to become invalid if the user authorizes too many applications?! Is this correct? How should the application react in such situations? Ask for another refresh token?
Thanks in advance.
EDIT: I created a test PHP script that would request refresh tokens from 4 Google clients (by client I mean generated credentials in the Dev console). Three of them are linked to one gmail address and the forth to a different one. For the first email, I generated 2 projects and for the first project, I generated 2 client ids. So:
email X, project A, client id abc
email X, project A, client id def
email X, project B, client id mno
email Y, project C, client id xyz
I started the test by requesting a refresh token for each client. Then I requested 24 more refresh tokens for the first client id abc. At this point all refresh tokens were valid even though for email X I had 27 refresh tokens. Then when I requested another refresh token for client with id abc, the first one for this client got invalidated, so hitting the 25 token limit per email/client combination. All other tokens were still valid and I managed to generate new tokens for client def. This client is for the same project A and the same email X. So I can't hit the second limit. What do these statements mean is still a complete mistery to me:
https://developers.google.com/accounts/docs/OAuth2#expiration
If you need to authorize multiple programs, machines, or devices, one
workaround is to limit the number of clients that you authorize per
user account to 15 or 20. If you are a Google Apps admin, you can
create additional admin users and use them to authorize some of the
clients.
https://developers.google.com/accounts/docs/OAuth2WebServer#refresh
Note that there are limits on the number of refresh tokens that will
be issued; one limit per client/user combination, and another per user
across all clients.
It actually isn't as bad as you think. Refresh tokens are application specific, that meaning specific to your client id. If the user installs your application a number of times then they have a number of Refresh tokens related to your application.
I ran into this issue with a SSIS Connection manager if the user had my connection manager running on more then 20 SSIS packages the first one the installed would stop working.
https://developers.google.com/accounts/docs/OAuth2#expiration
Token expiration
You should write your code to anticipate the possibility that a granted token might
no longer work.
A token might stop working for one of these reasons:
The user has revoked access.
The token has not been used for six months.
The user account has exceeded a certain number of token requests.
There is currently a 25-token limit per Google user account. If a user
account has 25 valid - tokens, the next authentication request
succeeds, but quietly invalidates the oldest outstanding token without
any user-visible warning.
If you need to authorize multiple programs, machines, or devices, one
workaround is to limit the number of clients that you authorize per
user account to 15 or 20. If you are a Google Apps admin, you can
create additional admin users and use them to authorize some of the
clients.
So as long as your application isn't being installed more then 15 times by the same user you shouldn't have a problem. If it is a problem you can suggest that they use a different / dedicated login for your application.

How to handle Facebook's deprecation of offline_access when you use token both in both iOS app and a server

Facebook's deprecation of the offline_access permission is coming May 2012 and the documentation isn't giving us enough information on how to handle it.
We have an iOS app and corresponding service that powers it and integrates with Facebook in a deep way to leverage a user's friend list within out app (so if your FB friends are also using the app you can more easily connect). This is like how all social apps seem to work, so nothing special here.
Client
Our app uses Facebook iOS SDK to allow user to login, which we currently ask for offline_access. The token is persisted in our iOS app, but also sent to our server where it is saved. The client acts on behalf of user to post updates to a user's newsfeed (we also ask for publish_stream permission).
Server
Our server periodically checks to see if user's FB friends are now using our app. Next time user signs in, we expose content and relationships in a certain way to promote that user's friends. The server also acts on behalf of the user to periodically connect to the graph API and get the user's current friends list. This is so we can account for changes in a user's relationships and have them reflected in our app. We do this when the user isn't currently using the app so they have the best experience the next time they do use it. To enable this, our iOS app sends the access token to our server which it uses and why we ask for offline_access.
Note: If user signs out of our app explicitly, we delete the access tokens from both client and server.
Problems
Now that there is no longer a perpetual access token we can use, I'm trying to figure out the best practice for still enabling our scenarios while leveraging facebook's new intended way of handling and extending access tokens. The documentation is unfortunately not totally helpful.
Questions
A. When you authenticate through the newest Facebook iOS SDK, what is the default lifetime of the access token you get? This document says an extended token request will give you one that lasts 60 days. This other document talks about the first access token request and mentions varying validities but it's unclear and does it talk about specific validity times:
(emphasis is mine)
When you obtain an access token from Facebook, it will be valid
immediately and usable in requests to the API for some time period
defined by Facebook. After that period has elapsed, the access token
is considered to have expired and the user will need to be
authenticated again in order for your app to obtain a fresh access
token. The duration for which a given access token is valid depends on
how it was generated.
There are also events which may cause an access token to become
invalid before its expected expiry time. Such events include the user
changing their password, an application refreshing it's App Secret.
Dealing with varying access token expiry times, and handling the case
when an access token becomes invalid before its expected expiry time
is essential for building robust social experiences.
B. For the client, now that the access token isn't necessarily long lived, is the right approach for us to:
Let use login through FB, then detect whenever the access token is expired. If it is, then call into FB iOS SDK to re-authentication/re-authorize? (this should just trigger user to bounce out to FB iOS app, and in most cases come immediately back to our app with a new access token).
C. According to this blog post I found, you can only extend an access token once:
Can I exchange my 60 day access token for a new 60 day access token?
No, sorry you cannot. You can only exchange a valid (meaning current)
user access token for an extended one. You cannot extend an already
extended access token.
On the client, I can just handle this by prompting a re-authentication/re-authorization as I mentioned in Question B. However, this doesn't work on our server. We could certainly have the server renew it once to 60 days, but what happens on the 61st day? The server just stops being able to sync the friend's list?
D. It seems to make sense to check the validity of the FB access token every time the app starts or re-hydrates from sleep. What is the best way for our iOS app to check this? Is there a recommended endpoint to call to validate a token? Should we just call into https://graph.facebook.com/me passing the access token and checking the response?
Note: we can certainly record the expires time when we get the initially extended token, but this isn't reliable since the user could revoke our app's permission anytime which makes the expires time an unreliable data point on validity
Overview
I believe that the root of what facebook is trying to achieve is to prevent an app from having perpetual ever-lasting access to a user's account. So, with the new migration an app can only access an account for 60 days unless the user signs in again.
I don't work for facebook, but here are my findings from playing around with the facebook graph api.
General Solution
Whenever a user signs in, take their access token and immediately extend/refresh it, and save it
Record the expiration date of the access token
When an access token expires (either from the recorded date, or a graph API exception telling you so), then notify the user that you don't have access, and ask them to sign in again.
Answers
A. When you authenticate through the newest Facebook iOS SDK, what is the default lifetime of the access token you get? This document says an extended token request will give you one that lasts 60 days. This other document talks about the first access token request and mentions varying validities but it's unclear and does it talk about specific validity times:
Here's how it works:
The first sign-in grants you approximately two hours
By refreshing the access token, you can get up to 60 days
If the user doesn't sign in to those 60 days, there is no way to get access for longer without having them sign in.
If the user de-authorizes your app, that 60 day windows ends immediately, and you will no longer have access.
B. For the client, now that the access token isn't necessarily long lived, is the right approach for us to: Let use login through FB, then detect whenever the access token is expired. If it is, then call into FB iOS SDK to re-authentication/re-authorize? (this should just trigger user to bounce out to FB iOS app, and in most cases come immediately back to our app with a new access token).
If the users access token is expired, your only option is to have them go through a login loop like you are talking about.
C. According to this blog post I found, you can only extend an access token once. On the client, I can just handle this by prompting a re-authentication/re-authorization as I mentioned in Question B. However, this doesn't work on our server. We could certainly have the server renew it once to 60 days, but what happens on the 61st day? The server just stops being able to sync the friend's list?
You can only extend an access token once. On the 61st day, you are out of luck. Best notify the user and let them know that unless they sign in, you won't be able to do anything.
D. It seems to make sense to check the validity of the FB access token every time the app starts or re-hydrates from sleep. What is the best way for our iOS app to check this? Is there a recommended endpoint to call to validate a token? Should we just call into https://graph.facebook.com/me passing the access token and checking the response?
I haven't be able to find an API equivalent of the Debug Console. This FB blog article talks about invalidated access tokens, but doesn't mention any API methods in particular meant to test the API.
I your suggestion of hitting https://graph.facebook.com/me would work just fine is exactly what they recommend in their example. In fact, I might use this approach in my app as a pro-active way of checking an access token.
Tid Bits
When you "refresh" an access token, a new access token will be returned. The response looks like: access_token=TOKEN&expires=5183912
You can only "refresh" an access token once. If you try to "refresh" the long-lived token returned from a previous call, it will return the same token, but doesn't throw an exception unless the token has expired. (in other words, you can safely try to refresh your token)
The default access token length seems to be around 2 hours
If you "refresh" an access token, that new access tokens seems to be the one that you'll get from the facebook API afterwards (instead of returning the original, short-lived access token)
Also, if you want to play around, these tools make it easy to test out your use case in a browser before burying it in your code:
Graph API Explorer - For creating and getting access tokens
Debug Console - For checking the expiry date of tokens before/after refresh
Refresh Endpoint - For manually testing extending your tokens
Great answer, one important addition : the default token lasts between 1 and 2 hours. You get the remaining of the hour during which the user signs up, plus 1 full hour. For example if a user signs up at 3:45pm, the access token will expire at 5pm. To be safe developers should assume it only lasts 1hour.

Resources