Managing users authentication in Google App Engine

本小妞迷上赌 提交于 2019-12-01 06:04:18

I understand the confusion, but the system is "working as designed".

At any point in time a GAE handler can have zero or one "logged-in user" (the object returned by users.get_current_user(), or None if no logged-in user) and zero or more "oauth2 authorization tokens" (for whatever users and scopes have been granted and not revoked).

There is no constraint that forces the oauth2 thingies to match, in any sense, the "logged-in user, if any".

I would recommend checking out the very simple sample at https://code.google.com/p/google-api-python-client/source/browse/samples/appengine/main.py (to run it, you'll have to clone the whole "google-api-python-client" package, then copy into the google-api-python-client/source/browse/samples/appengine directory directories apiclient/ and oauth2client/ from this same package as well as httplib2 from https://github.com/jcgregorio/httplib2 -- and also customize the client_secrets.json -- however, you don't need to run it, just to read and follow the code).

This sample doesn't even use users.get_current_user() -- it doesn't need it nor care about it: it only shows how to use oauth2, and there is no connection between holding an oauth2-authorized token, and the users service. (This allows you for example to have cron execute on behalf of one or more users certain tasks later -- cron doesn't log in, but it doesn't matter -- if the oauth2 tokens are properly stored and retrieved then it can use them).

So the code makes a decorator from the client secrets, with scope='https://www.googleapis.com/auth/plus.me', then uses @decorator.oauth_required on a handler's get to ensure authorization, and with the decorator's authorized http, it fetches

user = service.people().get(userId='me').execute(http=http)

with service built earlier as discovery.build("plus", "v1", http=http) (with a different non-authorized http).

Should you run this locally, it's easy to add a fake login (remember, user login is faked with dev_appserver) so that users.get_current_user() returns princess@bride.com or whatever other fake email you input at the fake login screen -- and this in no way inhibits the completely separate oauth2 flow from still performing as intended (i.e, exactly the same way as it does without any such fake login).

If you deploy the modified app (with an extra user login) to production, the login will have to be a real one -- but it's just as indifferent to, and separate from, the oauth2 part of the app.

If your application's logic does require constraining the oauth2 token to the specific user who's also logged into your app, you'll have to implement this yourself -- e.g by setting scope to 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.profile.emails.read' (plus whatever else you need), you'll get from service.people().get(userId='me') a user object with (among many other things) an emails attribute in which you can check that the authorization token is for the user with the email you intended to authorize (and take remedial action otherwise, e.g via a logout URL &c). ((This can be done more simply and in any case I doubt you really need such functionality, but, just wanted to mention it)).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!