2011-10-18 18 views
10

Quiero configurar una API de reposo con un proveedor de Oauth 2.0 para autenticación. Utilizo python. ¿hay alguna biblioteca para configurar un proveedor de oauth 2.0 codificado en python que se ejecute en el motor de la aplicación? Gracias.proveedor de motor de aplicación google oauth2

Respuesta

2

¿Has echado un vistazo a la información del artículo OAuth for Python? Dice que es para "Esta referencia describe cómo usar OAuth con aplicaciones de Python como proveedor de servicios".

+0

que utiliza Google para la autenticación no mi servicio que hace que mi autenticación de depender completamente de Google! – neo

+0

Luego mira [python-oauth2] (https://github.com/simplegeo/python-oauth2) para una implementación completa de OAuth en Python. –

+1

creo que, a pesar del nombre, se puede usar para crear solo proveedores de oauth 1.0 – neo

22

Compatible con OAuth2 en los tiempos de ejecución de Python y Java App Engine.

En Python todo lo que necesita es:

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) 

En Java se debería utilizar:

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); 

Aquí está el controlador completo Python 2.7 que permitirá verificar el usuario:

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) 

La aplicación.yaml es trivial

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 

Tenga en cuenta que el cliente debe enviar el token OAuth2 en un encabezado de solicitud HTTP Authorization: Bearer, p. Ej.

Authorization: Bearer ya29XAHES6ZT4w72FecXjZu4ZWskTSX3x3OqYxUSTIrA2IfxDDPpI 

Si quieres pasar a ser la construcción de una aplicación para Android, se puede generar fácilmente estos símbolos utilizando la interfaz 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); 

Si desea ver todo en su conjunto, no dude en pago y envío estos proyectos para la fuente completo:

+0

¿está seguro? Afaik Gae solo es compatible con Oauth 1.0a – systempuntoout

+0

He probado tu código pero no funciona. Excepción: - Estaba usando Python 2.5. – Chameleon

+0

Miró alrededor de Google y StackOverflow. Esta es la única respuesta con buen código de trabajo que he encontrado. (ver las URL provistas para un ejemplo completo). También funcionó para Java, por lo tanto, el título de la pregunta puede confundir a los usuarios de Java. – Guy

0

que no puedo comentar sobre la respuesta anterior, así que he añadido aquí para cualquier persona que lucha con este fragmento:

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

Este se ha roto en App Engine durante un mes si está usando cuentas de servicio (y hasta el día de hoy, creo que también tokens de usuarios de Google) ya que la longitud del token causa problemas en la biblioteca de AE. Google me dijo que es poco probable que lo solucionen pronto.

Este es el único que funciona para mí, en este momento:

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'] 
+0

¿Qué hace esto? ¿Cuál es la lógica detrás de esto? – Praxiteles

+0

Utiliza una API de Google Api para 'decodificar' el token de portador, extrayendo la dirección de correo electrónico de la respuesta. – KevH

Cuestiones relacionadas