I am using OAuth2 Authentication, and I have a CMS with multiple users, each with their own profiles. It happens that our company has a Google account with access to multiple Analytics accounts. For each user who uses the CMS, I connect to the Google Analytics API using a different username, and each user’s token is saved in a database data store. The problem is, if one user disconnects and revokes his token, none of the other users who use the same Google account will be able to access the Analytics API either, which doesn’t make sense.
EDIT: After further investigation, I found that when the first user authenticates, the token saved in the data store contains a 'refresh_roken' as well as an 'access_token'. However, when other users authenticate (they use the same google account, but different Analytics accounts), their tokens will only contain the 'access_token'. If one of them revokes his token, all will lose their connections.
How can I stop this from happening and have each user receive his own refresh_token?
EDIT 2:
I do store separate rows in the data store, one for each user. Let me clarify - if you look at this diagram, imagine a CMS where one CMS user needs to see statistics from "Liz's Personal Account", and another CMS user needs to see stats from "Liz's Team Account".
Both CMS users are from the same company, and they both use the same google account - "[email protected]". CMS user A connects to the Analytics API using "[email protected]", receives a refresh_token and wants to view statistics for "Liz's Website". Then CMS user B connects to the Analytics API also using "[email protected]", but now he doesn't receive a refresh_token anymore, only an access_token - this is a problem because the user will be asked again to connect after the access_token expires.
What I was normally doing when one user was disconnecting was to delete the token from the data store AND revoke the token, but maybe I shouldn't revoke it, should I? In any case, if in my scenario user A disconnects, this deletes his data store token, which means we won't have the refresh_token stored anymore, as user B didn't have it in the first place.
User accounts diagram:
I think you need to check databaseDatastore. If done correctly your database datastore should be storing refreshTokens for each of your users identified by userName
in your code.
When a new user authenticates you should be inserting a new row in the database for them.
// New User we insert it into the database
string insertString = "INSERT INTO [dbo].[GoogleUser] ([username],[RefreshToken],[Userid]) " +
" VALUES (@key,@value,'1' )";
Then when you want to access it again you should be selecting it out by again by username
using (SqlCommand command = new SqlCommand("select RefreshToken from GoogleUser where UserName = @username;", myConnection))
If for some reason it doesn't work then you should delete only this one user. it almost sounds like if one authentication fails you are deleting them all.
// Deletes the users data.
string deleteString = "delete [dbo].[GoogleUser] from " +
" where username = @key";
Without seeing how you have implemented databasedatastore I cant help more, but this is my version of databasedatastore.cs
Update:
If you are only accessing a single Google Analytics account you should be using a Service account.
Update in response to your update
You need to have a look at my database datastore. But seriously you should not have more then one user using the same gmail account.
Step one:
User [email protected] logs into your app authenticates the app, a row should be inserted into your database username [email protected] with a refreshtoken. your databasedatastore should handle saveing it.
when the access token expires assuming that you have created databasedatastore correctly it will use the refreshtoken to automaticly get a new access token for user name [email protected].
Step 2:
Some other person logs in with [email protected], database data store checks the database for user name [email protected] and gets the refresh token associated with [email protected] and requests a new access token.
You should not be deleting refresh tokens or users from the database unless for some reason it doesn't work. It may not work if a user went to the Google account and revoked your access. There should be only one username [email protected] and refresh token associated for it.
Service account:
A service account is a type of authentication that doesn't require a user to authenticate it. It works by creating a service account authentication in the developer console then taking the email address and adding it to the Google analytics admin like you would any other user. Now the service account has access to the google analytics account directly just like a user.
Then your application request data from the API without prompting a user for access. You can show Liz , Jim and sue all the data with out asking them to authenticate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With