Google Cloud Storage Javascript anonymous upload - javascript

I want to use GCS to store pictures taken by users in my Cordova app. I have a first major issue : I can't figure out how to use GCS properly for that purpose. Every usable example in the documentation ( here or there for the auth process alone ) needs to give credentials from a Google account on the client side to be able to use the JSON API. I don't want that. Basically I want every people connected to my app to be able to upload freely to the wanted bucket. I thought about issuing tokens for every user of my app, etc... But first I need to be able to upload something anyhow, right ?
My current status is this :
function init() {
gapi.client.setApiKey(apiKey);
gapi.auth.authorize({
client_id: clientId,
scope: 'https://www.googleapis.com/auth/devstorage.full_control',
immediate: true
}, initializeApi);
}
function initializeApi() {
gapi.client.load('storage', 'v1').then(makeRequest);
}
function makeRequest() {
var request = gapi.client.storage.buckets.list({
'project': PROJECT
});
request.then(function(response) {
console.log(response);
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
}
And well, the log just gives me the error : "Error: Login Required" along with a 401 unauthorized on
https://content.googleapis.com/storage/v1/b?project=PROJECT&key=apiKey
Well, since I provided everything I had, I guess I need some sort of authentication token. I simply didn't find anywhere how to do that.
The only lead I have would be this : service accounts and it absolutely doesn't sound like something fit for client side code.
Thanks ahead !

Related

Keycloak JavaScript API to get current logged in user

We plan to use keycloak to secure a bunch of web apps, some written in Java, some in JavaScript (with React).
After the user is logged in by keycloak, each of those web apps needs to retrieve the user that is logged in and the realm/client roles that the user has.
For Java apps, we tried the keycloak Java API (request -> KeycloakSecurityContext -> getIdToken -> getPreferredUsername/getOtherClaims). They seem to work fine
For JavaScript apps, we tried the following code, but could not get Keycloak to init successfully (Note this is in web app code after the user is already authenticated by keycloak, the app is only trying to retrieve who logged in with what roles):
var kc = Keycloak({
url: 'https://135.112.123.194:8666/auth',
realm: 'oneRealm',
clientId: 'main'
});
//this does not work as it can't find the keycloak.json file under WEB-INF
//var kc = Keycloak('./keycloak.json');
kc.init().success(function () {
console.log("kc.idToken.preferred_username: " + kc.idToken.preferred_username);
alert(JSON.stringify(kc.tokenParsed));
var authenticatedUser = kc.idTokenParsed.name;
console.log(authenticatedUser);
}).error(function () {
window.location.reload();
});
I assume it would be fairly common that web apps need to retrieve current user info. Anyone knows why the above code didn't work?
Thanks.
<script src="http://localhost:8080/auth/js/keycloak.js" type="text/javascript"></script>
<script type="text/javascript">
const keycloak = Keycloak({
"realm": "yourRealm",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required": "external",
"resource": "yourRealm/keep it default",
"public-client": true,
"confidential-port": 0,
"url": 'http://localhost:8080/auth',
"clientId": 'yourClientId',
"enable-cors": true
});
const loadData = () => {
console.log(keycloak.subject);
if (keycloak.idToken) {
document.location.href = "?user="+keycloak.idTokenParsed.preferred_username;
console.log('IDToken');
console.log(keycloak.idTokenParsed.preferred_username);
console.log(keycloak.idTokenParsed.email);
console.log(keycloak.idTokenParsed.name);
console.log(keycloak.idTokenParsed.given_name);
console.log(keycloak.idTokenParsed.family_name);
} else {
keycloak.loadUserProfile(function() {
console.log('Account Service');
console.log(keycloak.profile.username);
console.log(keycloak.profile.email);
console.log(keycloak.profile.firstName + ' ' + keycloak.profile.lastName);
console.log(keycloak.profile.firstName);
console.log(keycloak.profile.lastName);
}, function() {
console.log('Failed to retrieve user details. Please enable claims or account role');
});
}
};
const loadFailure = () => {
console.log('Failed to load data. Check console log');
};
const reloadData = () => {
keycloak.updateToken(10)
.success(loadData)
.error(() => {
console.log('Failed to load data. User is logged out.');
});
}
keycloak.init({ onLoad: 'login-required' }).success(reloadData);
</script>
simple javascript client authentication no frameworks.
for people who are still looking...
Your code asks the Keycloak client library to initialize, but it doesn't perform a login of the user or a check if the user is already logged in.
Please see the manual for details: http://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter
What your probably want to do:
Add check-sso to the init to check if the user is logged in and to retrieve the credentials keycloak.init({ onLoad: 'check-sso' ... }). You might even use login-required.
Make sure that you register a separate client for the front-end. While the Java backend client is of type confidential (or bearer only), the JavaScript client is of type public.
You find a very minimal example here: https://github.com/ahus1/keycloak-dropwizard-integration/blob/master/keycloak-dropwizard-bearer/src/main/resources/assets/ajax/app.js
Alternatively you can register a callback for onAuthSuccess to be notified once the user information has been retrieved.
Once you use Keycloak in the front-end, you will soon want to look in bearer tokens when calling REST resources in the backend.
You might have solved the problem by this time. I hope this answer help rest of the people in trouble.
when you use JavaScript Adopter
Below javascript should be added in of html page.
<script src="http://localhost:8080/auth/js/keycloak.js"></script>
<script>
/* If the keycloak.json file is in a different location you can specify it:
Try adding file to application first, if you fail try the another method mentioned below. Both works perfectly.
var keycloak = Keycloak('http://localhost:8080/myapp/keycloak.json'); */
/* Else you can declare constructor manually */
var keycloak = Keycloak({
url: 'http://localhost:8080/auth',
realm: 'Internal_Projects',
clientId: 'payments'
});
keycloak.init({ onLoad: 'login-required' }).then(function(authenticated) {
alert(authenticated ? 'authenticated' : 'not authenticated');
}).catch(function() {
alert('failed to initialize');
});
function logout() {
//
keycloak.logout('http://auth-server/auth/realms/Internal_Projects/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri')
//alert("Logged Out");
}
</script>
https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter Reference Link.
Note : Read the comments for 2 methods of adding json credentials.

OAuth 2.0 authentication silently failing in Google Blogger JavaScript API (v3)

Until recently I was using the javascript Blogger API v3 to fetch posts from a blog to build an automated index, using the gapi.client.blogger.posts.list() method.
However, it suddenly stopped working. The response now simply includes an error object with the message "We're sorry, but the requested resource could not be found.", as if the blog I'm trying to fetch info does not exist at all. I'm pretty sure my blog ID did not change during my sleep.
So I started digging around, and I found that the OAuth authentication token returned says I'm not actually logged in Google. In the status object from the token, the signed_in property is true but the google_logged_in one is false. Yet the Google login page showed up correctly upon execution and I allowed it, and the token does not have an error property. Why does it says I'm not logged in?
I'm under the assumption that Google blocked my application from making new requests due repeated use (even thought I never reached a dent of the daily quota) and now since the OAuth 2 ID authentication does not work, the API tries to use only the web browser API key, which does not work either since it's a private blog and user permission is required. But I really don't know.
I could not find a similar situation on the internet. I tried deleting both my API and OAuth keys and making new ones, deleting the project from the Google Console Developers and creating a new one under a different account, removing the application from the "allowed apps" in my account and adding it again, not using the browser API key. No game.
I would appreciate any inputs in solving this issue. And before anyone suggests: the "conventional" way of creating an automated index using the blog's feed does not work in my case, since the blog is private and has no feed.
Bellow is the returned access token (redacted a bit):
{
_aa: "1"
access_token: "[Redacted]"
client_id: "[Redacted]"
cookie_policy: undefined
expires_at: "1460999668"
expires_in: "3600"
g_user_cookie_policy: undefined
issued_at: "1460996068"
response_type: "token"
scope: "https://www.googleapis.com/auth/blogger.readonly"
state: ""
status: {
google_logged_in: false
method: "AUTO"
signed_in: true
}
token_type: "Bearer"
}
And bellow an example code of my application:
var apiKey = "myWebBrowserApiKey";
var clientId = "myOAuth2ClientID";
var blogId = "myBlogID";
var bloggerReadOnly = "https://www.googleapis.com/auth/blogger.readonly";
var fetchParam = {
blogId: blogId,
fetchBodies: false,
fetchImages: false,
maxResults: 500,
status: "live",
view: "READER"
};
var authParamIm = {
client_id: clientId,
scope: bloggerReadOnly,
immediate: true
};
var authParam = {
client_id: clientId,
scope: bloggerReadOnly,
immediate: false
};
//Executed as soon the client:blogger.js loads
function handleClientLoad() {
gapi.client.setApiKey(apiKey);
window.setTimeout(checkAuth,1);
}
//Check if the user is already authenticated for immediate access
function checkAuth() {
gapi.auth.authorize( authParamIm, handleAuthResult );
}
function handleAuthResult(authResult) {
//If the user does already have authorization, proceed with the API call
if (authResult && !authResult.error) {
makeApiCall();
}
//If he does not, shows the authorization button
else {
authorizeButton.css('visibility', 'visible');
authorizeButton.click(handleAuthClick);
}
}
//The authorization button calls this function, that shows a Google login page
function handleAuthClick(event) {
gapi.auth.authorize( authParam, handleAuthResult );
return false;
}
//Loads the Blogger API, version 3, and runs the fetchPosts() function with a callback
function makeApiCall(){
gapi.client.load('blogger', 'v3', fetchPosts);
}
function fetchPosts(){
//Creates a request to get a list of posts from the blog, using the fetch parameters
var request = gapi.client.blogger.posts.list(fetchParam);
//Execute the request and treats the response with a callback function
request.execute(function(response){
//Do Stuff
}
}

Any way to carry the gapi.client object on multiple pages?

I want to have two flows where in on the first page I just ask the user to signin.
Then if he/she wants to invite friends, I want to fire the gapi.client.people.list method and retrieve the visible circle list.
As I am doing this on two seperate pages, I am not able to carry through the gapi object which has been authenticated. I don't want to trigger the signin flow again but if I directly do gapi.client.load, it gives me an error saying Daily unauthenticated usage limit exceeded.
function getFriends(e)
{
gapi.client.load('plus','v1', function(){
//gapi.client.setApiKey("myKey");
var request = gapi.client.plus.people.list({
'userId': 'me',
'collection': 'visible'
});
request.execute(function(people) {
console.log(people);
$('#googleFriends').empty();
$('#googleFriends').append('Number of people visible to this app: ' +
people.totalItems + '<br/>');
for (var personIndex in people.items) {
person = people.items[personIndex];
$('#googleFriends').append('<img src="' + person.image.url + '">');
}
});
});
}
Is there a solution here? I tried using gapi.client.setApiKey but that keeps returning an invalid key error.
I have read and tried to understand google quickstart tutorial but there they call the people.list as part of signin flow.
If the user already signed-in/authorized your app, you can use the gapi.auth.authorize method with the same client_id and scope parameters you have used for the Sign-in, and immediate set to true.
gapi.auth.authorize({
client_id: 'your_client_id',
scope: 'your_scopes',
immediate: true
}, function (authResult) {
// check authresult and then call getFriends
});
This will go through the auth process without any user interaction necessary and gapi.client will then be able to make authorized calls. You will have to check the response in the callback though, to make sure you are actually authorized.
Docs: https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiauthauthorize

Google Javascript API (gapi) - problems with .load

I am trying to use the Google plus API (via googie-api-javascript) implementation like so (omitting full code):
var clientId = '7454475891XxxxxxXom4c6n.apps.googleusercontent.com'; //fake client
var apiKey = '-uTH_p6NokbrXXXXXXXXXXXXX'; //Fake Key
var scopes = 'https://www.googleapis.com/auth/plus.me';
function handleClientLoad() {
gapi.client.setApiKey(apiKey);
window.setTimeout(checkAuth,1);
}
function checkAuth() {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
makeApiCall();
} else {
//handle user-approval
}
}
// Load the API and make an API call. Display the results on the screen.
function makeApiCall() {
gapi.client.load('plus', 'v1', function() {
var o = gapi.client.plus;
alert(o);
});
}
The code works well upto the point of gapi.client.load (including the user allowing access) - this callback gets called but alert(o) will return undefined.
Upon inspecting the HTTP request I see the .load issues a request to:
https://content.googleapis.com/discovery/v1/apis/plus/v1/rpc?fields=methods%2F*%2Fid&pp=0&key=-uTH_p6NokbrXXXXXXXX
This returns HTTP 400 with the following message:
{"error":{"errors":[{"domain":"usageLimits","reason":"keyInvalid","message":"Bad Request"}],"code":400,"message":"Bad Request"}}
My question is - what do I need to change to make this work?
Is there some secret setting I need to enable ? Google+ is enabled in the google-developer-console under the APIs list.
Thanks for the help,
Alon
Problem:
.load issues a request to the google discovery service to load the .JS. The service will error out if the request it receives contains an api-key. (I don't know why the library works like this, it seems like a bug?)
Fix:
gapi.client.setApiKey(""); //NEW
gapi.client.load('plus', 'v1', function()
//re-add the key later if you need it
From Discovery Service docs:
requests you make to the Discovery Service API should not include an API key. If you do provide a key, the requests will fail.
Weird... :P
A little update & more of an explanation. The current Discovery Service page is a little more specific now. They indicate that if the app has an Oauth2 token, then the API Key value is not required. However, I also found that if I have an authenticated user and thus an Oauth2 token (access_token) present, the Discovery Service fails with the error noted in the OP. This seems to contradict the documentation.
You can see the token in the developer tools console with:
console.log(gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse());
Embed that somewhere in a <script>...</script>in your HTML or in a .js file that is called otherwise. Must be after gapi.load(...). It'll stop the script if executed before gapi.load(...) is called.
To get a current user this has to be after the user is authenticated, of course. It does return an object if a user has not been authenticated however. If you are in Chrome, you can expand The Object in the developer tools console window to get a nice outline format of all the stuff in the auth response.
Note that currentUser is undefined prior to a successful authentication. Since this 'fails silently' you should use a conditional statement to verify either the sign in status or that a current user exists in your real code.
For completeness the object instantiation process in my app goes like this, at a high level:
1.) gapi.load(...) - After this gapi.client, gapi.auth2 and other objects are available.
2.) gapi.client.setApiKey("") would be called to 'clear' the api key if it had been set previously for some other purpose.
3.) gapi.auth2.init(...) - After this the auth instance is available via gapi.auth2.getAuthInstance .
4.) Then the login is kicked off using the .signIn() method of the auth instance. The auth instance would be instantiated with something like auth_instance = gapi.auth2.getAuthInstance(); If that's how you do it then the sign in would be auth_instance.signIn().
(...) - means there are several parameters needed.
I also found the Google tictactoe example useful as an example and a simple base for further work.
I hope this is helpful to someone!
you need to call the method
function handleAuthClick(event) {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false} handleAuthResult);
return false;
}
function makeApiCall() {
gapi.client.load('plus', 'v1', function () {
var request = gapi.client.plus.people.get({
'userId': 'me'
});
request.execute(function (resp) {
'method ajax with you application'
});
});
}
you can see what this do here

Keep getting a "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup" when attempting to google plus login on my web app

I'm trying to implement Google plus sign up on my web app and I followed the google docs to set up the sign up however when I attempt a signup after accepting permissions and using the access token returned to me any api restcall I make returns the Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup error. I have already signed up my app with a ouath 2.0 key, so I don't seem to get what I'm doing wrong. Here is my code.
Cient Side:
const clientId = "5XXX000XX.apps.googleusercontent.com";
const apiKey = "AIzaSyCAXE5JSa36jcC*X7HV40SBcIWBiVGUTBE";
const scopes = "https://www.googleapis.com/auth/plus.login";
let accessToken = null;
function initer() {
gapi.client.setApiKey(apiKey);
// alert("Hello init");
if ($("#authorize-button").length > 0) {
$("#authorize-button").click(onLoginClick);
}
}
function onLoginClick() {
// $("#modalLoading").modal();
// alert("yeah");
gapi.auth.authorize({ client_id: clientId, scope: scopes, immediate: false }, onConnect);
}
function onConnect(authResult) {
// alert("On connect");
if (authResult && !authResult.error) {
alert("Hey");
accessToken = authResult.access_token;
triggerLogin();
} else {
alert("Error");
}
}
triggerLogin = function() {
alert("Triggering login");
$("#modalLoading").modal();
$.ajax({
url: window.config.site_root + "account/google_login",
type: "POST",
data: "access_token=" + accessToken,
success: onLogin,
error() {
onError("Logging In", "starting your session");
},
});
};
onLogin = function(login) {
alert("Login start");
$("#modalLoading").modal("hide");
if (login.operation) {
location.reload();
} else {
alert("Register will start");
triggerRegistration();
}
};
triggerRegistration = function() {
$("#modalLoading").modal();
$.ajax({
url: window.config.site_root + "account/google_registration",
type: "POST",
data: "access_token=" + accessToken,
success: onRegistration,
error() {
alert("An Error");
},
});
};
onRegistration = function(data) {
alert("Handling register");
$("#modalLoading").modal("hide");
if (data.account_exists) {
stage.showErrorModal(
"Account already registered",
"There is already an account with that email address, are you sure you created an account using this login method?",
);
} else if (data.operation) {
alert("Login now");
triggerLogin();
} else {
alert("Error");
onError("Registering", "creating your account");
}
};
Here is my server side code
public function google_registration()
{
$access_token = (isset($_POST["access_token"]) && !empty($_POST["access_token"])) ? $_POST["access_token"] : null;
$name = null;
$email = null;
$account_id = null;
$picture = null;
$gender = null;
try
{
if($access_token)
{
$me = file_get_contents("https://www.googleapis.com/plus/v1/people/me?access_token=".$access_token);
if($me)
{
$me = json_decode($me);
$name = $me->name.formatted;
$email = $me->email;
$account_id = $me->id;
$picture = $me->image;
$gender = ($me->gender == "female") ? 1 : 0;
}
}
}
catch(Exception $error)
{
// let the system handle the error quietly.
}
return $this->service_registration("google", $name, $email, $account_id, $picture, $gender);
}
I too ran into the same error - "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup".
I went and checked my google developer console under APIs for the project associated with the API key/ auth key, eg, https://console.developers.google.com/project/<your app id>/apiui/api. The status for Google+API was set to OFF. I turned it ON.
I then got another access token, and then tried with the new one. It worked, ie, the error was gone and I got the profile details. To cross-check if that was indeed the cause of the error, I went back to console and disabled Google+ API. But now, I get the error:
"Access Not Configured. Please use Google Developers Console to activate the API for your project."
So, I am not 100% sure that it was the turning on/off of the Google+ API in my developer console, but do ensure that this is turned on. Also, wait a few minutes after turning on, and ensure that you get a fresh token each time before trying it.
Make sure you have Google+ Api here enabled.
Without it you will get errors like:
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
To enable it:
1) open https://console.developers.google.com
2) choose your project (top right corner)
3) search for "Google+ API" in search box and enable it if it is not enabled already.
This issue happens when you are already logged in and still try to login again and again. I faced same error so did some experiments 1) I opened website on my mobile and everything was fine. 2) Then i tried on another laptop and used different gmail account to login and it again worked fine. 3) On my first laptop i tied again by clicking "Signin" button i got same error, so i opened google.com then logged out completely and then tried again, this time it worked. So i believe, Issue is clicking login button again and again without logout.
I am not sure if this is a really a issue, but atleast this is what i found. I am still trying, trying and trying , will post if i found anything else.
Cheers !!
You have to add the apiKey with the URL:
$curl = curl_init( 'https://www.googleapis.com/urlshortener/v1/url?key=AIza3834-Key' );
So I ran into this issue and the above two methods/solutions (enabling API access, and signing out of accounts) did not work for me because for google+ signin you have to pass in the access token in the authorization header of the http call.
Here's how you do it via jQuery:
$.ajax({
type: "GET",
url: "https://www.googleapis.com/plus/v1/people/me",
headers: {
"Authorization":"Bearer " + {access_token},
}
});
It seems your issue is with the server side code where you pass in access_token in the params (which is not necessary).
Here's my attempt on what the PHP implementation would look like:
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Authorization: Bearer ".$access_token
)
);
$context = stream_context_create($opts);
// Open the file using the HTTP headers set above
$file = file_get_contents('https://www.googleapis.com/plus/v1/people/me', false, $context);'
Hopefully you're sending that access token over https! It might be worth considering using the code instead and doing an exchange on the server side for an access token, for improved security if nothing else, there's some documentation on that approach here: https://developers.google.com/+/web/signin/server-side-flow
With regards to the problem you're seeing, it seems like the access token is bad, or not making it through correctly. Can you check the access token that you receive against the tokeninfo endpoint: https://www.googleapis.com/oauth2/v1/tokeninfo?access_token= - that should show valid information. Nothing stands out as being off in the code, but if the token is getting mangled you might see a similar error.
I got have the same issue, The solution is: set APIKEY
I was also desperate, and finally I managed to find a solution. The only problem is to add the correct api token linked to your app, in my case was the browser token, and it all works.
Example: I wanted to have all the events associated with my calendar
https://www.googleapis.com/calendar/v3/calendars/{calendar_id}/events?&key={api_key}
maybe I will help someone who is having the same problem.
Good Luck
I was trying to use access_token to fetch a returning user's name and picture when they already logged in during a prior session. After running into the "unauthenticated use" error message, this is what finally worked via cURL in PHP.
//initialize provider specific params for oauth2
$access_token = <fetched from app database from last login> //remember to never expose this to users
$api_url = 'https://www.googleapis.com/plus/v1/people/me';
$headers = [
'Authorization: Bearer '.$access_token
];
//send curl request
$curl = curl_init();
$curl_opts = [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 0, //GET
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => 1,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_URL => $api_url,
CURLOPT_HTTPHEADER => $headers,
];
curl_setopt_array($curl, $curl_opts);
$curl_response = json_decode(curl_exec($curl), true);
$curl_status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
//parse curl response from provider into name and icon fields for my app
$name = $curl_response['displayName'];
$icon = $curl_response['image']['url'];
Note that https://www.googleapis.com/plus/v1/people/me (for returning users via access_token) and https://www.googleapis.com/oauth2/v4/token (for initial login via code) return the user name and picture in different fields/structures.
I had a problem on JavaScript side (Client Side).
In my case it was necessary to add API_KEY to gapi.client.init()
Full my function:
async function initClient () {
return new Promise((resolve, reject) => {
const API_KEY = "YOUR_GOOGLE_API_KEY"
const CLIENT_ID = "YOUR_GOOGLE_OAUTH2_CLIENT_ID"
const DISCOVERY_DOCS = ['https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest']
const SCOPES = 'https://www.googleapis.com/auth/youtube.readonly'
const initData = { apiKey: API_KEY, clientId: CLIENT_ID, discoveryDocs: DISCOVERY_DOCS, scope: SCOPES }
gapi.client.init(initData).then(function () {
// YOUR CODE HERE
}, function (error) {
reject(new Error('Reject Error: ' + error))
})
.catch(err => console.log('Catch Error', err))
})
}
API_KEY and CLIENT_ID can be taken from here (Google Cloud Platform -> APIs & Services -> Credentials -> Credentials [Tab])
In my case, it happened at a specific time of the day, After spending few hours finally found that my daily quota limit (Queries per 100 seconds) was exceeded at that time because of a high number of requests. so it was throwing the error. I have contacted google support to increase them.
In my case, it was because I was using an old access token. You must keep in mind that access tokens have a short life span, so you must use the refresh token to generate a new access token. Example (using a PHP Class):
// Get the access token from DB or filesystem
$accessToken = $this->getAccessToken();
// Set the access token
$this->client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($this->client->isAccessTokenExpired()) {
$this->client->fetchAccessTokenWithRefreshToken($this->client->getRefreshToken());
// Save the new access token to DB or filesystem
$this->saveAccessToken($this->client->getAccessToken());
}
I just had same problem and found out what was wrong.
When you enable your Google Plus API from your Library, there is extra steps to completely activate. You have to click "Manage" button in the Google Plus API Library page and fill up two question answer and submit. That's all!!
This fixed my issue and I hope its fixes yours as well. Here is the screenshot of that page where i was taken after I clicked "Manage" button which says "Add credentials to your project".
I'm getting the following error:
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use
requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use
requires signup."
}
}
I'm not sure but i think its caused in my case on the OAuth consent Screen of the Google Developers Console, there is this message,
The user cap limits the number of users that can grant permission to your app when requesting unapproved sensitive or restricted scopes. The user cap applies over the entire lifetime of the project, and it cannot be reset or changed. Verified apps will still display the user cap on this page, but the user cap does not apply if you are requesting only approved sensitive or restricted scopes. If your users are seeing the "unverified app" screen , it is because your OAuth request includes additional scopes that haven't been approved.
I'm requesting restricted scopes:
private val SCOPES: List<String> = arrayListOf(DriveScopes.DRIVE_FILE, DriveScopes.DRIVE_APPDATA, DriveScopes.DRIVE)
Although my app is in development it seems to require verification, I think over the lifetime of the development of my app i have signed in over 100 times. (See OAuth user quotas)
https://support.google.com/cloud/answer/7454865?authuser=0
I Guess i have to verify my App Does anyone know if this is the case...?
I think (at least for some) this error could be leading them in the wrong direction. In my case, my API call was working, then suddenly stopped. Here was my thought process while working through this error, hopefully it will help someone:
OBSERVATIONS
New error was produced
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
}
This occurred during a test attempting to send an update to the Google Calendar API with the following call:
service.events().patch(calendarId='primary', eventId=id, sendNotifications=True, body=update).execute()
This occurred shortly after I updated the data in my time_start variable referenced in the json that gets sent to google:
update = {
'start': {
'dateTime': time_start, # Specifically this variable (time_start) was changed
'timeZone': time_zone,
},
'end': {
'dateTime': time_end,
'timeZone': time_zone,
},
'description': description,
}
The information in my time_start variable changed from:
2020-05-13T17:06:42-07:00 to 2020-05-13T17:06:42 (note the missing UTC offset)
ACTIONS
Updated my code populating time_start to include the missing UTC offset that was being passed to google calendar API.
RESULTS
The payload successfully transmitted to google calendar and my event was patched with the update
Just in case someone has gotten this issue while using Drive API (in my case, using Python as programming language), this can also occur due to an incorrect metadata update. Here is my error report:
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
}
This was, in essence, due to the fact that I was trying to alter both copyRequiresWriterPermission and viewersCanCopyContent fields over an application/vnd.google-apps.folder, which is not allowed.
No clue about why Google chose to send an error report so unrelated to the actual error.
This is because the scope you use for Drive API is labelled restricted.
You can make a limited number of requests to get file data/content.
Once you have reached the limit you have to get another access_token for the existing session. It is like having refresh_token.
You can wrap your code that sends requests to get files in try...catch
If that error is thrown you can requestAccessToken.
NOTE: For refreshing the access token in an existing session, you do not need to ask for content again.

Categories

Resources