I am developing an Android application with a GAE backend, for sessions etc.
I want to use Google Cloud Endpoint and develop an API with custom authentication user model. I dont want to use the google's oauth. I want to implement a simple email/pass user authentication model with a session based token. I have no experience on GAE whatsoever. I have worked in python and it's frameworks(django, flask, etc).
I have looked for a sample project of this kind for past week(with no luck).
Can someone please provide me with sample code/resource on how to implement such an endpoint with session management and csrf protection along with ssl?
Ps: If you think cloud endpoints is not a good approach for my application(server backend) then please direct me to a source that may aid me in creating my own RESTful api with JSON encoding + crsf-protection and session management.
I have already seen the following but none of them have a detailed solution:
Custom Authentication for Google Cloud Endpoints (instead of OAuth2)
Google App Engine: Endpoints authentication when custom auth or Open ID is used
AppEngine Cloud Endpoints and custom Users service
You're in for a ride. It's not a simple process, but I've managed to do just what you're looking for--albeit in a slightly hackish way.
First, there's a boilerplate project for GAE (in Python) that implements a custom email/pwd login system using webapp2's extras: http://appengine.beecoss.com/
It follows the guidelines for setting up custom authentication detailed in this blog post: http://blog.abahgat.com/2013/01/07/user-authentication-with-webapp2-on-google-app-engine/
This project will set things up so that your user will start a session upon login. Now, in order to access the user information on this session in your endpoints, you'll follow the instructions to that first StackOverflow link you posted.
The key, after following the previous steps, is to match the session key in your endpoints to the session key in the config file of the boilerplate code. Then, you'll be able to get which user made the request and follow through with the endpoint call if they're validated:
self.get_user_from_cookie()
if not self.user:
raise endpoints.UnauthorizedException('Invalid token.')
It is incredibly ridiculous that this is how it works for custom authentication, so if you're used to Django and would like to implement your app that way, DO IT. It was "too late to turn back now" for me, and I despise Google for only documenting authentication schemes that work for Google account holders only.
OP, just use Django on GAE and save yourself the frustration. I'm sure there's plenty of quick integration with mobile apps that the Django community can provide.
No one wants to force their app users to have Google accounts in order to log in, Google. Stop it.
Related
We have
An existing Django backend with Python social auth for signing in with Google, providing web-based application and an API for the mobile app.
An iOS mobile app with GoogleSignIn pod.
Now we would like to allow mobile app users to sign in with Google inside the app, and then authenticate them on the backend, so that they can access their personal data via the app.
So my idea of the algorithm is:
App uses the GoogleSignIn and finally receives access_token.
App sends this access_token to the Backend.
Backend verifies this access_token, fetches/creates the user, returns some sessionid to the App.
App uses this sessionid for further requests.
The problem is with the third step: token verification. I found two ways of verifying:
1. Python social auth flow
As described in the docs:
token = request.GET.get('access_token')
user = request.backend.do_auth(token)
if user:
login(request, user)
return 'OK'
else:
return 'ERROR'
This would be a preferred flow, since it already has all the required steps and is working perfectly with the web app (like, accounts creation, defaults for newly created users, analytics collection, etc.).
But the problem is that the backend and the app use different CLIENT_IDs for the auth. This is due to the limitations in the Google Developers Console: when creating credentials, you need to select whether it will be a web app or an iOS app, and it cannot be both.
I tried to use different client ids (then backend cannot verify), tried to use web id inside the app (then the pod does not work), and tried to use app id inside the web (then the backend cannot verify again).
2. Google API Client Library
Another option is to utilize the way from the Google Sign-In for iOS documentation:
from google.oauth2 import id_token
from google.auth.transport import requests
try:
idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)
userid = idinfo['sub']
except ValueError:
# Invalid token
pass
It worked, but here we're missing all the pipeline provided by social auth (e.g. we need to create a user somehow), and I could not find a proper way of starting the pipeline from the middle, and I'm afraid it would be quite fragile and bug-prone code.
Another problem with this solution is that in reality we also have Signed in with Apple and Sign in with Facebook, and this solution will demand ad-hoc coding for each of these backends, which also bring more mess and unreliability.
3. Webview
Third option would be not to use SDKs in the Swift and just use a web view with the web application, as in the browser.
This solves the problem with the pipeline and client ids.
But it doesn't look native, and some users may suspect phishing attempts (how does it differ from a malicious app trying to steal Google identity by crafting the same-looking form?). Also, I'm not sure it will play nicely with the accounts configured on the device. And it also will require us to open a browser even for signing in with Apple, which looks somewhat awkward. And we're not sure such an app will pass the review.
But, maybe, these all are minor concerns?
⁂
So, what do you think? Is there a fourth option? Or maybe improvements to the options above? How is it solved in your app?
I am implementing micro-services on google app engine standard environment.
I need to call one micro-service from another using URLfetch. For this I have to have some authentication mechanism in place so that only micro-service in the same project can only call this api.
It can be achieved using task queues but that is not useful for my scenario.
I followed this link (How to secure connection between different GAEs?) and
If we verify X-Appengine-Inbound-Appid headers then this can be achieved.
I am curious if we make this further more secure using service accounts.
Below links have reference to do it https://cloud.google.com/appengine/docs/standard/python/communicating-between-services
https://cloud.google.com/docs/authentication/production
but did not find clear instructions to achieve it. Anyone is using this approach for authentication?
This link [1] that you mentioned has clear instructions along with code examples in Python (click the Python tab) to achieve your objective. The documentation shows how to create a service account, assign it a role with the associated permissions, and providing the credentials to your application.
The code examples showcase how you can have an App interact with the Cloud Storage micro-service. If you get an error while following the examples, please provide the error details.
[1] https://cloud.google.com/docs/authentication/production
One option would be to enable Cloud Identity-Aware Proxy (IAP) for your App Engine applications. You can then authenticate programmatically using a service account. This would allow one App Engine app to call another protected by IAP in an authenticated manner.
I'm trying to implement a secure google cloud endpoint in python for multi-clients (js / ios / android)
I want my users to be able to log by three ways loginForm / Google / Facebook.
I read a lot of docummentation about that but I didn't realy understood how I have to handle connection flow and session (or something else) to keep my users logged.
I'm also looking for a way to debug my endpoint by displaying objects like Request for exemple.
If someone know a good tutorial talking about that, it will be verry helpfull.
thank you
For request details, add 'HttpServletRequest' (java) to your API function parameter.
For Google authentication, add 'User' (java) to your API function parameter and integrate with Google login on client.
For twitter integration, use Google app-engine OpenID.
For facebook/loginForm, its all on you to develop a custom auth.
I've got an app currently running on Google App Engine that takes advantage of the close integration with Google Accounts to the extent that it was the only way users would sign in. The sign-in process was this:
User would click sign-in w/ Google Account link, which would just be the output of `users.create_login_url()`
User would sign-in on Google-themed page.
User would be signed-in
Now I'm moving away from App Engine to a host with vanilla Django. I'd like to replicate that login process as much as possible, I guess using OpenID (or OAuth? I'm not sure). I'm not sure exactly how to do so, though. Would I use Django's auth APIs and just use the user's Google Account data to sign them in?
I've followed the instructions here, and now have functional little demo where I get the user's Google Account address. But that really doesn't help me much.
Anyone have experience with this, or have an idea of how one would accomplish this?
Since you can't use the App Engine API to do so (and you probably don't want to write this OpenID auth system by yourself), you better make use of a django app to do so. Have a look at Django packages. I personally have good experience with django-socialregistration, though they provide Facebook/Twitter auth as well. There also OpenID only packages available.
I'm developing a django app that integrates with google apps. I'd like to let the users login with their google apps accounts (accounts in google hosted domains, not google accounts) so they can access their docs, calendar, and whatnot.
In order to do it, I downloaded and started using django_openid_auth (and thus, python-openid).
First, to test it, I used this url in my settings:
OPENID_SSO_SERVER_URL = 'https://www.google.com/accounts/o8/id'
And with that I managed to redirect the user to the google accounts page to login and then to return to my own domain, with the authentication cycle described by the google folks successfuly completed. However, to login to google accounts is of little use for me, as I'd like the users who have a google apps account in their hosted domain -but not a google account- to login with.
In order to do that, I read the google article on discovery " Discovering OpenID Endpoints for Hosted Domains", and changed the aforementioned setting to:
OPENID_SSO_SERVER_URL = 'https://www.google.com/accounts/o8/site-xrds?hd=<my-domain>.com'
-where, obviously, <my-domain> is my actual domain ;)
But the backend responded with the following message:
OpenID authentication failed: HTTP
Response status from identity URL host
is not 200. Got status 404
Debugging a little, I managed to find out that the code in python-openid (version 2.2.4) is the one that is misinterpreting the response from google, but I'm quite at loss here.
I have seen the authentication in my own domain work in socialwok.com and puffypoodles.com So I'm quite certain that the auth cycle for my google apps domain works, but somehow python-openid can't seem to complete it (though, and I reiterate, it works just fine with plain old google accounts).
Should I try to fix python-openid, or is there another way to fix this? Has anyone successfuly managed to login with google apps in a pure django app (not in google app engine)?
According to http://groups.google.com/group/google-federated-login-api/web/openid-discovery-for-hosted-domains, Google changed the way of IdP Discovery and user XRDS check a little bit to give Google Apps users openid in http://example.com/openid?id=108441225163454056756 kind of format without asking the users to build their own openid servers. For small companies, people can get their openid under their domain with as few as just a domain name if they use Google Apps.
This might be a good approach because people could use their Google Apps Account for the authentication, and they can still give out openids under their own domain which they could change the authentication backend for in the future. It is simple and extendable, but sadly it hasn't became the standard yet. So, if you use standard library like python-openid, you will encounter some problems.
To solve those problems, you have to patch python-openid yourself to follow Google's approach.
I ran into the same problem before and I have a patched version of python-openid v2.1.1 which works for me.
If you need, I could post my code after some cleanup. It was a quick patch, so don't expect too much :)
I think you can give a try http://github.com/hudora/django-googleappsauth
but I found some bugs trying to fix them and translating comments