2011-10-18 22 views
10

Voglio configurare un ripristino API con un provider oauth 2.0 per l'autenticazione. Uso Python. c'è qualche libreria per configurare un provider oauth 2.0 codificato in python che gira su app engine? Grazie.fornitore di google app engine oauth2

risposta

2

Avete controllato le informazioni dell'articolo OAuth for Python? Dice che è per "Questo riferimento descrive come utilizzare OAuth con le applicazioni Python come fornitore di servizi."

+0

che utilizza Google per l'autenticazione non il servizio che rende la mia autenticazione completamente dipendere da google! – neo

+0

Quindi guarda [python-oauth2] (https://github.com/simplegeo/python-oauth2) per un'implementazione OAuth completa in Python. –

+1

penso che nonostante il nome possa essere usato per creare solo provider oauth 1.0 – neo

22

Supporto OAuth2 incorporato in entrambi i runtime di Python e Java App Engine.

In Python tutto ciò che serve è:

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) 

In Java si usa:

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

Ecco il completo gestore di Python 2.7, che vi permetterà di verificare l'utente:

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) 

L'app.yaml è banale

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 

Si noti che il client deve inviare il token OAuth2 in un'intestazione di richiesta HTTP Authorization: Bearer, ad es.

Authorization: Bearer ya29XAHES6ZT4w72FecXjZu4ZWskTSX3x3OqYxUSTIrA2IfxDDPpI 

Se vi capita di essere la costruzione di un app Android, si può facilmente generare questi token utilizzando l'interfaccia 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); 

Se vuoi vedere tutto mettere insieme, sentitevi liberi di cassa questi progetti per il sorgente completo:

+0

sei sicuro? Afaik Gae supporta solo Oauth 1.0a – systempuntoout

+0

Sono stato testato il codice ma non è stato prodotto alcun risultato - Eccezione: - Ero in uso python 2.5. – Chameleon

+0

Abbiamo guardato intorno a Google e StackOverflow. Questa è l'unica risposta con un buon codice di lavoro che ho trovato. (vedi gli URL forniti per un esempio completo). Anche per Java, il titolo della domanda potrebbe essere fuorviante per gli utenti java. – Guy

0

Non posso commentare la risposta di cui sopra in modo da ho aggiunto qui per tutti coloro che lottano con questo frammento:

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

Questo è stato interrotto su AppEngine per un mese se si utilizzano account di servizio (e oggi, penso anche token utente di Google) poiché la lunghezza del token causa problemi nella libreria AE. Google mi ha detto che è improbabile che risolverlo presto.

Questa è l'unica cosa che funziona per me, in questo 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

Cosa fa questo? Qual è la logica dietro? – Praxiteles

+0

Utilizza google rest api per "decodificare" il token bearer, estraendo l'indirizzo email dalla risposta. – KevH