google app engine поставщик oauth2 - PullRequest
       19

google app engine поставщик oauth2

10 голосов
/ 18 октября 2011

Я хочу настроить api rest с провайдером oauth 2.0 для аутентификации. Я использую python.есть ли библиотека для настройки провайдера oauth 2.0, написанного на python, который работает на движке приложения?Спасибо.

Ответы [ 3 ]

22 голосов
/ 01 июня 2012

Поддержка OAuth2 встроена в Python и Java App Engine.

В Python все, что вам нужно:

from google.appengine.api import oauth

# Note, unlike in the Android app below, there's no 'oauth2:' prefix here
SCOPE = 'https://www.googleapis.com/auth/userinfo.email'

# magic happens here
user = oauth.get_current_user(SCOPE)

В Java вы должны использовать:

OAuthService oauth = OAuthServiceFactory.getOAuthService();

// Note, unlike in the Android app below, there's no 'oauth2:' prefix here
String SCOPE = "https://www.googleapis.com/auth/userinfo.email";

// magic happens here
User user = oauth.getCurrentUser(SCOPE);

Вот полный обработчик Python 2.7, который позволит вам проверить пользователя:

from google.appengine.api import oauth
import logging
import traceback
import webapp2


class MainHandler(webapp2.RequestHandler):

  def post(self):
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.write('Hi there!\n')

    # Note, unlike in the Android app below, there's no 'oauth2:' prefix here
    scope = 'https://www.googleapis.com/auth/userinfo.email'
    try:
      self.response.write('\noauth.get_current_user(%s)' % repr(scope))

      # validates audience of the OAuth2 access token
      allowed_clients = ['407408718192.apps.googleusercontent.com'] # list your client ids here
      token_audience = oauth.get_client_id(scope)
      if token_audience not in allowed_clients:
        raise oauth.OAuthRequestError('audience of token \'%s\' is not in allowed list (%s)' % (token_audience, allowed_clients))          

      # gets user object for the user represented by the oauth token
      user = oauth.get_current_user(scope)
      self.response.write(' = %s\n' % user)
      self.response.write('- auth_domain = %s\n' % user.auth_domain())
      self.response.write('- email       = %s\n' % user.email())
      self.response.write('- nickname    = %s\n' % user.nickname())
      self.response.write('- user_id     = %s\n' % user.user_id())
    except oauth.OAuthRequestError, e:
      self.response.set_status(401)
      self.response.write(' -> %s %s\n' % (e.__class__.__name__, e.message))
      logging.warn(traceback.format_exc())


app = webapp2.WSGIApplication([
  ('/.*', MainHandler)
], debug=True)

app.yaml тривиален

application: your-app-id
version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: .*
  script: main.app

Обратите внимание, что клиент должен отправить OAuth2токен в заголовке HTTP-запроса Authorization: Bearer, например,

Authorization: Bearer ya29XAHES6ZT4w72FecXjZu4ZWskTSX3x3OqYxUSTIrA2IfxDDPpI

Если вы создаете приложение для Android, вы можете легко сгенерировать эти токены с помощью интерфейса AccountManager:

AccountManager accountManager = AccountManager.get(this);
Account[] accounts = accountManager.getAccountsByType("com.google");

// TODO: Allow the user to specify which account to authenticate with
for (Account account : accounts) {
  Log.i(TAG, "- account.name = " + account.name);
}

// Note the "oauth2:" prefix here
String authTokenType = "oauth2:https://www.googleapis.com/auth/userinfo.email";

// Note: AccountManager will cache these token, even after they've expired.
// TODO: Invalidate expired tokens, either after auth fails, or preemptively via:
// accountManager.invalidateAuthToken(accounts[0].type, token);

accountManager.getAuthToken(accounts[0], authTokenType, null, this,
    new AccountManagerCallback<Bundle>() {
      @Override
      public void run(AccountManagerFuture<Bundle> future) {
        try {
          String token = future.getResult().getString(AccountManager.KEY_AUTHTOKEN);
          Log.i(TAG, "Got KEY_AUTHTOKEN: " + token);
          // Don't forget HTTP Header "Authorization: Bearer <token>"
          callAppEngineRestApi(token); // <---- Your code here
        } catch (OperationCanceledException e) {
          Log.i(TAG, "The user has denied you access to the API");
        } catch (Exception e) {
          Log.i(TAG, "Exception: ", e);
        }
      }
    }, null);

Если вы хотите, чтобы все было вместе, не стесняйтесь зайти на эти проекты, чтобы получить полный исходный код:

2 голосов
/ 18 октября 2011

Вы уже просмотрели информацию о статье OAuth для Python ? В нем говорится, что он предназначен для «Эта ссылка описывает, как использовать OAuth с приложениями Python в качестве поставщика услуг».

1 голос
/ 01 марта 2017

Я не могу прокомментировать приведенный выше ответ, поэтому я добавил его здесь для всех, кто борется с этим фрагментом:

# magic happens here
user = oauth.get_current_user(SCOPE)

Это было сломано в AppEngine в течение месяца, если вы используете сервисные учетные записи(и на сегодняшний день, я думаю, также токены пользователей Google), так как длина токена вызывает проблемы в библиотеке AE.Google сказал мне, что вряд ли это скоро исправят.

Это единственное, что работает для меня на данный момент:

    token = self.request.headers['Authorization'].split(' ')[1]
    url = 'https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=' + token
    oauth_response = urlfetch.fetch(url)
    if oauth_response.status_code != 200:
        raise Exception('Unable to authorise: {}/{}'.format(oauth_response.status_code, oauth_response.content))
    token_response = json.loads(oauth_response.content)
    email = token_response['email']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...