403 Forbidden Error from google API Javascript client - google-sheets-api

I am getting 403 Forbidden Error from google API Javascript client. Following is my code:
gapi.load('client', function () {
console.log('gapi.client loaded.');
var discoveryUrl = 'https://sheets.googleapis.com/$discovery/rest?version=v4';
gapi.client.load(discoveryUrl).then(function () {
console.log('gapi.client.sheets loaded.');
gapi.client
.init({
apiKey: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
clientId: '0000000000000-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
scope: 'https://www.googleapis.com/auth/spreadsheets',
})
.then(function () {
return gapi.client.sheets.spreadsheets.get({
spreadsheetId: spreadsheetId,
});
})
.then(
function (response) {
console.log(response);
},
function (response) {
console.log(response);
},
);
});
});
My application is running in servlet container and oauth2 is handled at server side. If I want to add authToken how can I do it?

You may check in this documentation the reasons why you are getting a 403 Forbidden Error. It indicates that the server understood the request but refuses to authorize it. A server that wishes to make public why the request has been forbidden can describe that reason in the response payload (if any).
If authentication credentials were provided in the request, the server considers them insufficient to grant access. The client SHOULD NOT automatically repeat the request with the same credentials. The client MAY repeat the request with new or different credentials. However, a request might be forbidden for reasons unrelated to the credentials.
If I want to add authToken how can I do it?
Follow this documentation about Authorize Requests. You can identify your application using an OAuth 2.0 token.
You may also check on these related threads:
Getting 403 forbidden when using the Google Sheets API and a service account
Make sure that you grant the service account access to the file.
Getting a 403 - Forbidden for Google Service Account

You will get this error if you are emulating a device within Chrome DevTools.
If you try going through the usual "Sign in with Google" flow, you will see the following error:
Error 403: disallowed_useragent
You can’t sign in from this screen because this app doesn’t comply with
Google’s secure browsers policy. If this app has a website, you can open
a web browser and try signing in from there.
You can let the app developer know that this app doesn’t comply with
Google’s secure browsers policy.
See Google's documentation on this topic.
A workaround is to switch to device emulation only after going through the authorization flows.

Related

enable basic auth at api gateway

I've set up an express basic auth using the express-basic-auth module.
const basicAuthFunc = basicAuth({
challenge: true,
users: { 'admin': s.BASIC_AUTH.ADMIN_PASS }
})
it works on localhost. I'm prompted with a popup js challenge.
i'm deploying to lambda function and using AWS API gateway.
the page does not present me with the challange. I just get the 401 directly.
I tried removing the basic auth and the page loads so it's just related to the basic auth.
what headers should I add to api gateway ?
tried this one :
https://medium.com/#Da_vidgf/http-basic-auth-with-api-gateway-and-serverless-5ae14ad0a270
adding WWW-Authenticate and 'Basic' to 401 response.
didn't work

How to get daemon access token for self account

I am trying to create a web app whose main task is fixing appointment.
I do not want to access any mail data of the logged in user.
I only want to implicitly login using an outlook account (my account) to which I have admin access. I want to connect with this account, fetch its calendar events and display the events to the logged in user so that the user can select any available spots.
I have registered my app in the azure portal and provided all the application permissions (earlier I tried with Delegated permissions as well; but I guess delegated permissions are not for my use case).
Thereafter, I tried to fetch the token for my profile using:
this.http.post(`https://login.microsoftonline.com/f8cdef31-a31e-4b4a-93e4-5f571e91255a/oauth2/v2.0/token`,
{
client_id: 'my-client-uuid',
scope: 'https://graph.microsoft.com/.default',
grant_type: 'client_credentials',
client_secret: '****myclientsecret****'
},
{
headers: {
Host: 'login.microsoftonline.com',
'Content-type': 'application/x-www-form-urlencoded'
}
}
).subscribe(resp => {
console.log(resp);
});
as suggested in this article.
However, my request fails while doing this and states that the request body must contain 'grant_type' when I am clearly sending that.
Can someone please suggest me how I can implicitly get data from my own outlook account in a web app.
Update: I used the suggestion from this, appears that the request is going through now. However, the browser throws CORS error saying that the server didn't have appropriate headers.
Update 2: Found this link, which seems to address the exact issue I am facing. I however already have the redirect URI for SPA. The issue still persists.

Cross-Origin Request Blocked error in HTTPS request

I have a standard HTTPS Axios request from my Frontend (which is based on Vue), to the our company's API which is on another server(server use SSL sertificate).
testApi() {
axios.get('https://rng-hub2.staging.rng:8001/rng/3/')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.finally(function () {
// always executed
});
},
Which cause an error like this:
In Firefox:
In Chrome the error looks like this:
As I was thinking, in browsed developing tools under tab of Netwerk -> Response, I should also see an error, which is true for Chrome, but eventyally is not true for Firefox.
So Chrome shows me:
But in the Firefox I receive my data in exactly right format:
Have any idea how I can retrieve this data correctly and assign it to the response variable in .then section?
About Cross-Origin Request Blocked error: API's server administrator told me, that he have added my IP to the CORS "trusted list". However I'm not sure, because according to this post: https://jonhilton.net/cross-origin-request-blocked/
in my Response Header I should receive an additional header with my local IP like:
Access-Control-Allow-Origin: http://192.168.32.44
But I'm not.
This proxy staff also didn't work:
How to deal with CORS error on Vue CLI 3?
Please give me hint what am I doing wrong
Found the solution. The problem was deeper then I thought. So short answer is: If you are working in local network, with different API servers, they might be certified with inner corporate CA (Certificate authority) to be able to communicate via HTTPS protocol. So what you need is, to ask from your server administrator to give you private_key with which you gonna sign all the request to a specific API. In guzzle its looks like this:
new GuzzleClient(['verify' => '/path/to/self-signed/cert.pem']);

how to protect my Web API Basic Authentication credentials

I've just started implementing Authentication in my Web API.
I want to start with Basic Authentication
I learned that i've to pass Username and Password in every request.
So, lets say i'm doing some Admin task and making API call for same like this:
$.ajax({
url: host + "homework/delete/" + $(this).data("id"),
type: 'DELETE',
headers:
{
Authorization: 'Basic ' + btoa(username + ':' + password)
},
success: function (d) {
$tr.remove();
},
error: function () {
alert("Error please try again");
}
});
So, although my username/password is in variable, but their value must be at page(source). whosoever access that page, can see those credentials.
That means, whosoever get to know the url of that page, can see the credentials.
If i put a login page, how should i check on admin page that this user is authenticated. Should i use Cookies? to set something if user is coming through login page?
To enhance security, I think there should be another approach. At first you need to authenticate to you service using username and password, and receive authentication token with limited lifetime, then you should use this token to access your services.
I think you have to choose another approach:
create a server side application with UI (PHP, Java, ...)
this application has a session management
the credentials are stored in the configuration of the server side app
the requests to the service which is secured by Basic Authentication are performed by the server app. The responses are delivered to the client
You can't hide the credentials if you are creating a client side JavaScript application. Another issue with your approach maybe this: does the secured service support CORS (cross origin resource sharing) ?

Signing into Backand Using BackAnd SDK

Attempting to sign in (and enter a session) using user credentials in an Angular app using the Backand SDK. From the Backand docs I am attempting to sign in using the Backand.signin() method (from my local) which looks to be initially sending an OPTIONS http request to the API which unfortunately is causing this cross origin error:
XMLHttpRequest cannot load https://api.backand.com/token. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:xxxx' is therefore not allowed access. The response had HTTP status code 400.
The exact response from the endpoint is: {"error":"unsupported_grant_type"}
I've combed through the documentation extensively but can't find anyone else having these errors.
This is exact code I am using:
function Login(username, password, callback) {
Backand.signin(username, password).then(function(response){
console.log(response);
}, function(error){
console.log(error);
});
}
The error is logged to the console as a null object.
It looks like the error was in fact on my end.
While attempting to set up my own Authorization service in my Angular app I inadvertently was adding an encoded Authorization token header somehow. When the requests were being made to Backand from the Backand SDK, the headers were not correctly set and thus causing issues.