I've just updated to the latest version of the google-api-php-client. Can't find the previous version number I was running, but it's from back when it was on code.google.com. Definitely a few years old.
Getting this error, under specific circumstances.
{"error":{"errors":[{"domain":"global","reason":"insufficientPermissions","message":"User does not have sufficient permissions for this profile."}],"code":403,"message":"User does not have sufficient permissions for this profile."}}
This code used to work fine with the old version. What I'm doing is looping through a few google analytics accounts to read some data. I have the following code before the loop.
$client = new Google_Client();
$client->setApplicationName("name");
$client->setClientId('123.apps.googleusercontent.com');
$client->setClientSecret('secret');
$service = new Google_Service_Analytics($client);
Then inside the loop, for each account, I do $client->refreshToken($token). $token is the refresh token saved in the database. If I go through only one account, it works fine. The problem appears to be because I reuse the same Google_Client object. If I redefine Google_Client inside my loop, it works as intended. But that feels dirty, especially when the name, id, and secret are all the same. I should note that when I run $client->refreshToken($token) the access token is set correctly, which I confirmed with $client->getAccessToken().
Is there a proper way to reset the Google_Client object so I don't redefine it?
user does not have sufficient permissions for this profile
Means just that the user you have authenticated the script with does not have permission to access the profile you are trying to access.
You have not included any of the code used to access Google analytics but you should have something like view id or profile id in there some where. You need to login with a user with access to it.
Related
In the documents of Google One-Tap sign in, it says:
Returning users are signed in automatically, even when they switch devices or platforms, or after their session expires.
Question 1:
But it doesn't say anywhere how it does this? Is the user refresh token saved in the browser's cache? How can it then auto log in a user cross devices?
Question 2: The reason I ask is because I have a setup where I initialize the Google API client for JavaScript ("GAPI"). The GAPI library also automatically logs in a user whenever the client is "initialised" through gapi.client.init().
Now the problem is that after I have added the Google One-Tap code (Or should I say "YOLO code"? : ) my user gets logged in through One-Tap and also through GAPI. I can prevent this by not initializing the GAPI client, but I don't think that's wise, because I thought this whole library is built to manage my refresh tokens etc. Is my understanding correct that One-Tap does exactly the same and in case I only want to Authenticate users I do not need the GAPI client anymore?
Really, which library does a better job at managing my refresh tokens? And how do they differ? I'm clueless...
The way I implemented my login is the following:
Try to login in the user first using gapi.auth2. Maybe the user was previously signed into the site.
If can't login user automatically, then use googleyolo to try to find existing user accounts.
If no existing accounts, then present a signin button for user to signin.
I can give you some code snippet if you need.
To answer your questions.
#1, the credential is stored within the browser/device. If the user has never signed into google in a device, then yolo won't be able to sign in the user.
#2. googleyolo will also login the user, the difference is that it will give the account selector even if there's only one user to select (it will automatically login the user if there's only one). gapi simply sign in the user without showing anything.
Without changing my code or configuration, now google is asking users to grant permission every time when a user is trying to authenticate to my App. Even though the user already grated access and the scope didn't change.
I don't get any errors and the login works fine is just that now the google dialog asking for permissions appears every time.
To initialise google I use gapi.auth2.init with the "https://www.googleapis.com/auth/plus.profile.emails.read" as scope.
Also to request for access I use auth2.grantOfflineAccess.
I also checked in my Google account for Apps that have access and the application is registered successfully in there.
Anyone else has seen this issue? Or does know if google changed something in the way they handle permissions?
I believe I am seeing similar behavior... that the authentication flow has begun asking the user to grant the app permissions to the scopes every time they sign in. Previously, it would only proceed from sign-in to grant permissions the first time the user signed into the app. I haven't changed the scopes requested nor the underlying code recently... but also hadn't used the app in awhile (months?)
I'm using the oAuth2 server-side authentication and grantOfflineAccess() outlined here .
Given that there are no implementation details posted, i can't tell if the fix I found will apply to your situation.
The correction I found... so that the authentication only asks the user to grant the first time they sign into the app was to explicitly specify the "prompt" attribute when calling getOfflineAccess().
var auth2 = gapi.auth2.getAuthInstance();
auth2.grantOfflineAccess({
prompt : 'select_account'
}
).then(signInCallback);
https://developers.google.com/identity/protocols/OAuth2WebServer#offline
Check Step 1 prompt parameter
I recently noticed the addition of a "Session" object in Parse dashboard. Now, from what I understand, a session uniquely identifies a user to the server. So why would we need such a Session? For the session token? We already have a currentInstallation... so I don't really see the point. Can someone explain and provide a scenario where I would use the "Session" object. Right now they just annoy me by their presence because they take up potential space on the Parse server and I would like to go delete them all but want to make sure that isn't stupid.
The sessions are used by parse to deal with the users (is the user logged?, on which devices?, etc.), and are available as a class as you may want to manipulate them. By deleting the sessions you would automatically logout all your users, so it's a pretty bad idea.
You don't have to use or touch anything about this class, but here are few examples of why it can be useful:
[...] If a user contacts you about his or her account being compromised in your app, you can use the Data Browser, REST API, or Cloud Code to forcefully revoke user sessions using the Master Key. These new APIs also allow you build a “session manager” UI screen where your app’s users can see a list of all devices they’ve logged in with, and optionally log out of other devices. [...]
You can read more about the Sessions on their blog post.
I'm writing an app that's supposed to run with MVC5 and using parse as a backend.
I'm using the new Identity feature of the MVC5 to login an user. I also tried to use this solution but I couldn't make it work.
What is happening is that when I login with the user A and then login with the user B in a different session (a incognito windows or a new browser) whenever I try to insert something related with a ParseUser object using the first user that was logged in I get an exception: UserCannotBeAlteredWithoutSessionError.
I'm not sure if I'm doing the implementation in a wrong way, or if it is a limitation of the Parse (I think it was designed to run using one user per device).
If you have a workaround for this situation please help me.
There is a good answer which may help: Parse Database Authorization - Security For User Objects.
So, it's a kind of Parse SDK limitation, when you can work with only one user per device (as ParseUser is cached locally). The only workaround that I can see is to perform SignOut/Login explicitly, when you need to do something from other user's context. There is no way to have two users work simultaneously from the same device.
I'm looking for a good way for my application to know if the person needs to login (again) or not.
So meaning, if a person first uses the app, he needs to login. These login credentials are being verified by a webservice I've build. And after he is succesfully signed in, the next time he uses the application he doens't need to login again.
I've been looking around, but haven't found a clear solution.
I have read a few possibilities to handles this:
Storing this in a local database
Using the 'Settings plugin' from James Montemagno
Using local storage
Using KeyChain (IOS), KeyStore (Android)
It is not my entention to store the login credentials, only to remember if he has signed in previously or not.
Thanks you
You can use the 'Settings plugin' from James Montemagno to store a Boolean value ( LoggedIn = true or false).
But you might want to add a but more logic to your app. If someone is logged in, they should have a token that they'll use to communicate with your server...this token should have an expiry date and you should also have a refresh token.