I've got a GAE app that runs a publicly hosted dataset through a model via Flask, displaying the results. I successfully deployed it, and I can access & use it from the account that deployed it, but how do I make it publicly available? Right now from outside my account, I can access the app's index.html at its .appspot.com address, but when I press the app's run-the-model button, I'm taken to a login page instead of my model_result.html.
I've been trying to find an answer here, but am quickly getting out of my depth in terms of IAM terminology.
As Alex pointed out- my app.yaml request handlers need to be set for the behavior I wanted: login: optional (not login: required). Thanks!
Related
I've looked at previous questions enter link description here, but they use the GSuite Administrator to make changes, while my app uses GCloud. The domain registrar is separate since Google domains don't work in my country.
I mainly followed this guide to setting up my Zones and updating the name servers. I've configured the
https://cloud.google.com/dns/docs/update-name-servers
The question I linked to earlier recommended setting up a www. subdomain, but it used Authenticator. I'm not sure how to do this in a zone. I set up all the records properly in my domain registrar.
Here are the settings:
When I load the site itself (There's no actual HTTP response code):
And when I try the www. subdomain
I'm sure there's a step I'm missing, but this is my first site with GCloud. So I'm not very familiar with the process.
I think where is your missing step.
When you ask Google to use your domain, Google will expose HTTPS endpoint. HTTPS requires a certificate, and Google will generate it for you. However, before doing this, Google has to be sure that the domain belong to you.
You have to prove to google that you own your domain. For this, go to this page, log in and add a property (your website URL). Follow the instruction and be sure that your property has been validated.
Then, wait some minutes (hours?) the time that the certificates are generated and deployed.
I've read some info about authentication, but I would have thought that I could turn off my app's visibility and/or access to the public. This would be useful for alpha testing so surely a setting like this exists? Or do I need to build such things into the app itself?
Without some sort of authentication mechanism your app can't really distinguish between a request coming from you and one coming from someone else.
It might be a good idea to spend a bit of time to analyze your app's authentication requirements and maybe get it done now, while still in alpha.
Depending on the solution it may be fairly simple to integrate.
Google offers multiple authentication options, see What is the difference between Google identity toolkit, Google OAauth and Google+ sign in
I personally opted for the GIT kit for simplicity, flexibility and convenience.
It's possible secure your App's urls so only an authorised user or administrator can access them.
This can be done through the app.yaml file (Python, PHP and Go applications) or the web.xml deployment descriptor (Java applications).
Option A:
Just allow only admin access, in yourapp.yaml
- url: /*
login: admin
script: yourappname.app
Option B:
If you have an static IP (or with a few changes a week), you can detect the IP of the request and let run only from your IP:
class yourHandler(webapp2.RequestHandler):
def get(self):
userIP=self.request.remote_addr
if userIP=="220.123.211.120" # Change this with your static IP
...your code for authorized users.
Option C:
Check request domain (to ensure is called from your own authorized domains), and put some security client side.
class yourHandler(webapp2.RequestHandler):
def get(self):
origin=self.request.headers['Origin']
if origin=="www.yourdomain.com" # Change this with your domain/subdomain
...your code for authorized users.
# I recommend to put also the CORS headers for your own domain
self.response.headers['Access-Control-Allow-Origin'] = "www.yourdomain.com"
Personally, I have a mix of the three options plus a custom authentication to access private content.
By default, every service is born public. Change that, individually, by changing the --ingress setting for the service you want.
gcloud beta app services update <service-name> --ingress <value>
all (default): public to internet.
internal-only: only accessible for resources in the same Cloud Project.
internal-and-cloud-load-balancing: only accessible for resources in the same Cloud Project. And those requests came from configured Cloud Load Balancing.
1 Gateway + a bunch Microservices architecture example:
gcloud beta app services update ms-payment --ingress internal-only
gcloud beta app services update my-backend-gateway --ingress all << default!! Just for example purpose.
In this way, ms-payment is accessible only by resources within the same Cloud Project, even if they are in different VPCs.
Refer the documentation: https://cloud.google.com/appengine/docs/standard/java11/application-security#ingress_controls
I've found recently that you could also use IAP (Identity-Aware Proxy) IA-what? I found a tutorial that implements it on App Engine.
Tutorial for App Engine.
So I didn't want to rely on my own authentication implementation because I'm not an expert, and security it's something very hard to learn in a rush. In a nutshell
Deploy an IAP step 1
Add your app engine (or the whole scope) to your IAP
add your authorized emails on the left panel step 3. For access use:
IAP-Secured Web App User: Grants access to the app and other HTTPS
resources that use IAP.
My Personal opinion here: try to implement as many safety measures as possible (don't rely on one system only), usually they could fail.
This webpage appeared when I deployed my app on the App Engine and it seems anyone can access it and send messages to all the Android devices registered with my webapp. Although, there is an option to authenticate users before posting messages but I don't want even the users of my app to post messages to the registered devices. Is there a way to make this page accessible only to the app administrator?
Thanks in anticipation for taking the time to help me out!
I suggest that you use a feature available in App Engine console to provide Admin only pages. This feature allows you to define certain URLs/pages that will require an Administrator of your application to login. App Engine does all the heavy lifting for you and you would not really need to change your code too.
Check out the documentation : https://developers.google.com/appengine/docs/python/config/appconfig#Python_app_yaml_Administration_console_custom_pages
Once you configure it, the pages will appear inside of the App Engine console.
Assuming you are using webapp2 handlers to output this page, and storing the current username in a session variable, here is what you can do to perform this check just before writing this page on the response stream:
class Settings(BaseHandler):
def get(self):
template = JINJA_ENVIRONMENT.get_template('settings.html')
user=self.session['user']
if user=='admin': #validate your admin user here.
self.response.write( template.render(values) )
else:
self.redirect('/404') #or anything of your choosing
BaseHandler is a special class I've derived from webapp2.RequestHandler and included session handling features in it. Read my complete artcile to know more about it.
Firstly, just letting you know I have searched a fair bit here and I am aware of some of the other questions on this topic but none answer my question.
The authentication of the Local GAE differs from the appspot deploy and I need it not to with minimal work-around code.
I'm writing an HTML5 app and I can do the google authentication via a button and it updates all the correct tokens so I can access the profile in either GAE Launched apps or appspot deployed ones.
I need the google account details of the logged in user within the app
I am writing (for API calls to calendar and contacts for example)
, and I'd rather not have to write a login handler only for my local development platform - automated for simplicity or otherwise.
I've read that adding login:required forces a login, and on appspot this works perfectly. Locally it does nothing useful.
I've read that you can write a Python decorator to use #login_required - but I'm not writing in Python (It's php generating an HTML5 page). I could write a bit of a PHP wrapper to handle it, or automate a call in Javascript on page load - but this is the workaround I don't want to write because it's handled in the production environment for me.
I want the login:required option as everything is handled for me in
production
. I have googled the options for the login tag and nothing there suggests I can force a google login in the locally launched app. I have googled the launcher and settings, but nothing seems apparent.
I suppose I could live with the dev workaround, and the app could assume I'm authenticated and the JSON request handlers in my app would just use the login:required with the correct google tokens being passed once I am authenticated.
Do I have any other options?
This sounds like it could be a PHP runtime bug. login:required works fine on the python local dev server. Have you checked the issues page to see if it's been reported?
https://code.google.com/p/googleappengine/issues/list
Otherwise it's possible that it's bypassing the login on your dev server because you have some cookie in your browser indicating that you're already logged in. You might try clearing cookies
Alternatively (at least on the python devserver), you can go to your login page via http://localhost:8000/_ah/login to force a logout (obviously fix the hostname and port number)
There appears to be no way round this other than to write the whole OAuth handler yourself (or get one elsewhere) - significant overkill for a development environment only 'issue'.
I have written the app to handle the getting of the google profile details as it starts and force an authenticate if they are not present.
This means that the login:required will work as expected in the production world and force you to authenticate to google before you even get to the application... then the app just gets the profile details because the tokens are already present.
login:required in the dev environment just puts up a screen which you just 'ok', then the app attempts to gets the profile details but forces the authentication itself because there are no authentication tokens present.
It's unfortunate, but it's a single step in a development that users will not have to use, but it works.
We have added a custom domain to our appengine app. We followed the instructions when we made our changes, but apparently something went wrong and we can't find the way to fix it.
In our google apps appengine tab, the main URL specified is https://appid.appspot.com. That means, however, that all traffic from the domain mappings will be sent to the https url, and of course this won't work. I don't know how this https url ended up there as in the app engine admin console, the app url is http://appid.appspot.com.
We haven't find the way to change this url. We have tried to disable this app in google apps but it didn't work, it stays there.
in your app.ymal
-secure: optional
for more details:
http://code.google.com/appengine/docs/python/config/appconfig.html
scroll to Secure URLs