How to handle 3rd-level domains in Google App Engine? - google-app-engine

I develop Google App Engine application and want to provide separate 3rd-level domain for each registered user (e.g. username.example.com).What is the best way to handle such kind of features in App Engine?
Currently I see the only one way - set wildcard DNS A-record CNAME-record to point to the application's main address, handle all requests in the central request handler, then parse request's URL, fetch username from URL, and then apply logic neccessary for specified user. But it looks like error-prone approach since it involves manual work and assumptions.

You can't use an wildcard A record wildcard to point to the app; A records point to a single IP address and App Engine apps don't have a single IP address.
You need to use a wildcard CNAME record pointing to ghs.google.com.
Then, in your application, parse the hostname and act appropriately. I'm not sure what you mean by "manual work and assumptions"; it's fairly trivial to split the hostname on . and lookup whether there's a user registered with the first part of the hostname in your database.

Related

Storing users IP address in a DB in order to compare it later on

I'm quite new to React and after doing a Todo web app I've tried creating my first fullstack web app.
The app sends a request upon entering an Email and pressing a button that should send the users mail to a DB and get his IP which would also be stored into the same DB. This would later be used to check if the user had already done something on the site (After entering the email the client-s sent to the next page) and disallow the user to proceed if either the email or IP are already stored in the DB. What would be the best way to both grab the IP upon entering the email and what would be the best approach in regards of storing it into a DB? (Should I even store it there is there a better alternative).
I'm writing my code with Typescriptx and using Express for my backend & postgres for my DB.
TLDR: How to get the clients IP onClick / upon recieveing a request from them and store it in a database to later compare when the user sends the same request again
On the server side, you can get the IP address from the incoming request. That's the right way to do this (but see below: I think you probably don't want to do this).
In express, this is available via req.socket.remoteAddress. If you're behind some kind of reverse proxy like a CDN then this will give you the CDN's IP, not the real user, but all modern proxies will include the original IP in a request header such as X-Forwarded-For to work around this. You can get the IP from there instead, if that's present. You'll need to look at the docs for your specific infrastructure to check the header they use in this case.
That said, it sounds like you're trying to ensure each user can do exactly one thing, so that after sending an email nothing else is allowed. Is that right?
If that's the case, limiting it by IP address isn't a great solution. Two reasons:
Many users share an IP address, e.g. many many mobile users who are behind CGNAT, everybody sharing an office/home, etc etc
At the same time, many users have multiple IP addresses, e.g. offices that use multiple internet connections in parallel for failover or performance, or people taking their computer from their home to a cafe, etc etc.
In both cases, you'll end up blocking or allowing large numbers of users incorrectly. Typically this kind of thing is done with cookies/local storage on the client side instead, which lets you block this individual user's browser. That will work correctly in environments with shared IPs and environments with multiple IPs.
A client-side approach is not 100% secure, since a technical user could easily clear their cookies to avoid this. If you need a hard guarantee though then neither option would work (it's easy to change your IP too: go sit in the coffee shop outside, or use your phone as a hotspot). In that case, you need to tie the user to something they can't as easily change, maybe an email address, credit card, or even legal ID if you're seriously trying to lock this down hard.
I wouldn't bother: for most web app, client-side storage is usually the right choice.

How to forward domain requests to gae url

I have different customers who own each their own hosted saas page on my gae app. for example:
myapp.appspot.com/customer/123
myapp.appspot.com/customer/456
each of the customers may want his domain name for example theBigDomain.com to "invisibilly" forward to myapp.appspot.com/customer/123
Please notice I want theBigDomain.com/myservlet?id=theId#aBookmarkUrl to be transmitted to the target url as myapp.appspot.com/customer/123/myservlet?id=theId#aBookmarkUrl
I searched for the google documentation and I can't find a way to do that.
Note: I don't want a redirect where the person who types theBigDomain.com finds he's not there anymore, and I don't want a frame to include my url in the theBigDomain.com since I want the user to be able to click on the back button.
In short, I want the domains to work as proxies, knowing that from what I know, proxies are not good for some content, for exampe, if my target link has a youtube video, this might not work. So I'm asking if there is a way to do a dns redirect for a url and not a domain???
Using subdomains is also limited: creating a subdomain for each customer will be a tedious work...
Using subdomains is also limited: creating a subdomain for each customer will be a tedious work...
How so? This could actually be a lot easier for you/your customers since your customers wouldn't have to deal with domain verification/DNS settings and all you would need to do is add one * (wildcard) host to your main domain pointing to ghs.googlehosted.com and adding *.yourdomain.com in your GAE apps's settings. In your app, in your framework of choice you would then see what subdomain the request came to and and handle it as the customer's unique id (instead of 123/456). See here how you would determine the subdomain on python/webapp2. If you're using a different combination of language/framework - there are alternatives functions as well.
If you still want the customers to use their own domains then it gets a little more complicated. First, they need to provide the full domain name to you, you then add it to your GAE app's settings. Next, you and your customers need to follow one of the verifications steps listed on this page: https://support.google.com/a/answer/60216?hl=en and once that is complete you would need to ask your customers to create a CNAME record on their domains/subdomains pointing to ghs.googlehosted.com. Once the CNAME record is created, you would handle this just like the if these were subdomains on your own domain, i.e. in your framework determine what domain the request came to and handle it as a customer's unique ID to serve that customer's app.

send email on Google App Engine from custom domain

What I have done:
I have added my domain app.mydomain.com to my app engine project, and can successfully visit id.appspot.com using app.mydomain.com.
I have registered mydomain.com on google app for business.
The problem:
The problem is -- I am NOT able to send emails using #mydomain.com address. If I register an info#mydomain.com as an developer, this will probably solve the problem, but we need to send from more than one address, and I don't think registering a new developer for each address is reasonable.
Anybody knows how to solve this? Thanks!
You have two options:
Register all emails that you want to use as administrators/developers but as you mentioned in your post you don't want to do that.
Use SendGrid (or any other email services like Mandrill, Mailgun, etc.) which will give you a lot more features comparing to what GAE offers, including 25k free emails instead of GAE's 100.
According to the docs, the sender would need to be an administrator on the project (called "owner" in the new Developers Console). Another route would be to just use a separate email sending service like SendGrid or Postmark.
You can use the GMail API to send emails as users of your domain. Note that the emails need to be aliases, groups or users of your domain.
You shouldn't have any problem adding and verifying your domain, adding the necessary permissions to send emails. Then, every email address in your domain can be used. See here in the docs: https://developers.google.com/appengine/docs/java/mail/#Java_Sending_mail

Traffic Splitting By IP Address on Google App Engine

I'd like to direct traffic to different versions of Google App Engine code based on a set list of known IP Addresses.
For example, if an incoming request is from an IP Address on a given list, then traffic is directed to version 1. If not, then version 2.
Is there a way to do this from the admin console or deployment configuration?
The end goal is to grant access to extra features when the site is accessed from an approved IP Address. If I can't do this from the admin console, then I plan to get the IP Address during the user's login process, and set their security role based on IP.
There's not a way within the admin console or deployment process. However, if you do cookie-based traffic splitting, you can set the cookie yourself (based on the incoming IP address, or another value you desire). The value is stored in GOOGAPPUID and the value you'd want to use is described in the documentation, and varies depending on the number of versions you're splitting between and the respective levels of traffic you'd like to send to each version.
If you don't want to do traffic splitting for users not on a given list of IPs, you should make sure to explicitly set the cookie for all users. Otherwise, App Engine will provide the value (and send some users to both versions) by default.

Jespa ntlm authentication with multiple active directories or windows domains

I'm using Jespa to do transparent ntlm sign on. I want to be able to authenticate the users in multiple windows domains. I have it working with one domain. How do I add another?
Thanks
I asked this question to ioplex support. They gave me a good answer. Here it is:
"Only the first element in the chain can do SSO because once the HttpSecurityService challenges the browser with information for the first domain, the browser cannot start over for a different domain. At least not in the same request. Ideally it would be great if the browser submitted the name of it's own domain in the initial NTLM token. But unfortunately it simply does not.
We actually get this question quite a bit. The best way to handle this in our opinion is to create a custom Filter that creates multiple instances of the HttpSecurityService - one for each domain. Then you have a parallel list of network masks that can be used to match clients by remote IP address to the correct instance of the HttpSecurityService. Or you could identify clients using any method you want such as broswer signature. Or you could use a cookie to identify the ideal domain but in this case the user would have to do something to get the cookie (like login manually once). Do you understand what I mean?
Note that if the AD domains have trusts, SSO should work fine with only the one HttpSecurityService instance. The solution described above is only necessary if the domains do not have trust relationships."

Resources