Endpoints work on localhost but not on app engine (omitted https://) - google-app-engine

I would like to access my endpoint function without using OAuth.
I follow the guide on Simple access to API and tweak the code a little.
I can access the API on localhost - I have to wait for about five minutes for them to load. Then they appear in the explorer /_ah/api/explorer.
But I can't access the endpoint functions on app engine:
the functions load but I can't access them:
var rootpath = "//" + window.location.host + "/_ah/api";
gapi.client.load('helloworldendpoints', 'v1', makeRequest, rootpath);
// callback gets executed
...
var request = gapi.client.helloworldendpoints.sayHello();
//any code below this does not get executed

So this has been the most excruciating error for me in coding so far!:D
instead of
https://helloworld-146410.appspot.com/
https://1-dot-helloworld-146410.appspot.com/
I didn't include the https:// and used
helloworld-146410.appspot.com
1-dot-helloworld-146410.appspot.com
without https: I wasn't able to access the endpoints
Can I get the 30+ hours of my life back please?:D How could have I avoided this mistake or figured it out faster?

Related

401 Unauthorized calling my Azure Rest API

I have a Rest API using controllers, etc, hosted in Azure that has been working for some time. I want to secure the various methods. I added the API App (.NET core) to the App Registrations, and also added the javascript client app to App Registrations. I believe I'm initializing everything in startup.cs in the REST Api OK. I added [Authorize] to one of the methods. I used a simple javascript example which calls myMSALObj.loginPopup, and gets back a token which I then add to the Authorization header and make a fetch call. When I call, I see HTTP Error 401.0 - Unauthorized in the log stream for my App Service.
Any ideas how I can troubleshoot this to get more specifics about what is wrong?
Also, a related question: in App Registrations, Api Permissions, how does one correlate the API permission name with the method in the controller?
Add this in front of the method in the controller
[AuthorizeForScopes(Scopes = new[] { "My.Scope" })]

AngularJS - Request to localhost server fail

I have made an api end point using express.
Now im trying to get the data from my localhost server that is running on port 3010.
$scope.getBooks = function(){
$http.get('/api/books').then(function(resp){
$scope.books = resp;
});
}
The function is working good because i can test whit the JSONPlaceholder.com.
I cannot get my data, im using gulp on port 3002 and my server is in port 3010, he is running and working good, i can see my data using postman.
why can i get my data from the localhost server ?
Thank You
This issue happens because the API endpoint you are accessing does not implement CORS. If you run your code in Chrome and look at the console, you will see an error:
XMLHttpRequest cannot load .....
The solution is to change the API endpoint to set the Access-Control-Allow-Origin header to either the wildcard * or to the domain where the page using the JavaScript code will be served from.
For More Details on CORS
To prevent websites from tampering with each other, web browsers implement a security measure known as the same-origin policy. The same-origin policy lets resources (such as JavaScript) interact with resources from the same domain, but not with resources from a different domain. This provides security for the user by preventing abuse, such as running a script that reads the password field on a secure website.
If your site is on port 3002 and your server is on port 3010 then you must specify the URL of the entire server's location
$scope.getBooks = function(){
$http.get('http://localhost:3010/api/books').then(function(resp){
$scope.books = resp;
});
}
Specify the entire url in AngularJS code and use CORS middleware in the express backend.
https://github.com/expressjs/cors
This is bad way of doing front end(AngularJs) and backend development parallely on local on same machine. Try to fit Front-end repository to be hosted by BE server and use it in following way :
If you are doing FE development locally and backend server is also hosted locally.
use following line as common baseUrl
var baseUrl = "//" + window.location.host +'/'
Doing so, you don't need to update while committing changes to prod environment.
$scope.getBooks = function(){
var _url = baseUrl + '/api/books'
$http.get(_url).then(function(resp){
$scope.books = resp;
});
}
Above code works in case of same server FE and BE.
If you have different servers locally , you need to work more with setting :
You can use express-http-proxy
var proxy = require('express-http-proxy');
app.use('/api/', proxy('http://localhost:3010'));
In higher of version of angular 4+ , we have such setting as in initial configuration.
READ ARTICLE :
https://juristr.com/blog/2016/11/configure-proxy-api-angular-cli/
You cannot just write /api/books. You need to specify your port number of API running on localhost.
In your case localhost:3010/api/books

AngularJs + Django RESTful: session based authentication

I'm developing an angular web application that will replace the current website that we have. The current website uses session based authentication. At the moment, I can't access the hosted API with get or post requests.
I'm developing the angular application on my local computer using a python simple server, whereas the api is hosted online.
I would prefer to find a fix that's completely in angular since I can't change the API without help (it was written by my boss a while ago, and is now used in the production version). I don't have a login page so I'm just trying to provide the authentication information in my headers and requests.
My angular application was written independent of django. I just want to access the django backend
So far I'm trying the following to set the headers:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.headers.common = {'username': btoa('myUsername'), 'password': btoa('myPassword')
};
}]);
And in my service:
app.factory('Test', ['$resource', function($resource) {
return $resource('https://www.phonywebsite.org/en/api/test/')
};
I consistently get 301, 400 and 403 errors. Lately it's been mostly 301 errors and I get no response from the api. I'm using the Allow CORS chrome extension as a temporary fix to try to get to the api without getting a CORS policy error.
My questions
How can I fix the CORS errors without using the chrome extension?
How do I provide my authentication to my django backend that uses session based authentication making sure the csrf cookie its looking for is in the header?
To answer your first question, using the cors extension is a temporary solution and should mostly never be used cause your clients might not use it. To handle CORS, you need to understand how cross site API calls work. In short CORS is a mechanism that allows AJAX requests to circumvent their same origin limits. To handle such situations you need to update your backend and add
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
. Once you add this your settings.py should stop getting CORS issues.
To answer your second question, angular already provides you with support for CSRF so half of your battle is already won. What you need to do is add a patch on your module to start accepting csrf tokens (The name is a bit different in angular). You have already done this and done a good job of it as well:
var app = angular.module('app', ['...']);
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);
What this would do is make sure that whenever you make a $http call your csrf token is set as well.
As a learning oppurtunity, you could also try using ng-cookies as well. To go further to explain this, whenever you make a call in angular , your request in bundled with cookies as well so you can easily access them in request.COOKIES.
You need to change how you are calling your API as well, something like:
app.factory('APIService', function ($http) {
return $http({url: 'https://www.phonywebsite.org/en/api/test/',
method: 'GET'})
}
You can obviously make modifications to this but I think this shows the $http usage to make you understand the general gist.
You can try to add some more authentication around your application here as well (or replace django auth with your own custom auth), but that is on your use case.
Hope this helps.

Google cloud print OAuth scope not found

I'm creating an app that prints out a pdf from the server after it has been generated.
When using google cloud print I keep getting:
User credentials required
Error 403
Note: making this print request in the simulating page works fine, but that's because I'm already logged into my google account.
After doing some research I found out I need to use OAuth to get an access token to send with the request to make a print job.
And every single page I can find tells me to redirect me to: https://www.googleapis.com/auth/cloudprint, which gives me a 404 error, neither can I find it in the google playground, and using any older versions of authentication ends up in the request to sign in being flagged as an attack from a hacker.
Is there any way around this?
I was stuck on this for a while. The docs don't tell you which scope to use or how to use it. I haven't implemented a Google API using OAuth2 yet, so I didn't have an understanding of how the scoping works.
It turns out the scope is just the base API route for CloudPrint.
To make sure your refresh_token or access_token is scoped properly to use the CloudPrint API you need to use have the following string in your scope object:
https://www.googleapis.com/auth/cloudprint

How do I implement secure OAuth2 consumption in AngularJs?

I'm setting up oauth2 with Salesforce connect using AngularJS. When I attempt the initial GET using $http I get CORS errors - Access-Control-Allow-Origin not allowed for my client. However, using the hack below in my controller function works.
Is there a better way to do this in AngularJs given that I don't have control over the server? My backend is Firebase so it would be great if I could do this through FIrebase like I can for Facebook :
$scope.auth = function () {
var authUrl = $scope.AUTHORIZATION_ENDPOINT +
"?response_type=token" +
"&client_id=" + $scope.CLIENT_ID +
"&redirect_uri=" + "https://www.xyz/";
window.location = authUrl ;
The cors issue happens when make asynchronous call to different server via browser.
So it doesn't appear if the call is made from another server. so you have to use a proxy server which in turn makes a call to your actual server.
You can try the below proxy server which is straightforward.
https://www.npmjs.com/package/cors-anywhere
or you can write your own proxy server which runs on the same domain as your client app and proxies your request to the secured server.

Resources