1. Panoramica
La serie di codelab Serverless Migration Station (tutorial pratici e self-service) e i video correlati mirano ad aiutare gli sviluppatori Google Cloud serverless a modernizzare le applicazioni guidandoli attraverso una o più migrazioni, principalmente abbandonando i servizi legacy. In questo modo le tue app saranno più portabili e avrai più opzioni e flessibilità, consentendoti di integrare e accedere a una gamma più ampia di prodotti Cloud e di eseguire più facilmente l'upgrade a release delle lingue più recenti. Pur concentrandosi inizialmente sui primi utenti di Cloud, principalmente sviluppatori di App Engine (ambiente standard), questa serie è sufficientemente ampia da includere altre piattaforme serverless come Cloud Functions e Cloud Run, o altrove, se applicabile.
Lo scopo di questo codelab è mostrare agli sviluppatori di App Engine Python 2 come eseguire la migrazione da API/servizio App Engine Users a Cloud Identity Platform (GCIP). È prevista anche una migrazione implicita dall'NDB di App Engine a Cloud NDB per l'accesso a Datastore (trattata principalmente nel Modulo 2 sulla migrazione) nonché un upgrade a Python 3.
Il modulo 20 illustra come aggiungere l'utilizzo dell'API Users all'app di esempio del modulo 1. In questo modulo, acquisirai l'app completa del modulo 20 ed eseguirai la migrazione del suo utilizzo a Cloud Identity Platform.
Imparerai a utilizzare
- Sostituisci l'utilizzo del servizio Utenti di App Engine con Cloud Identity Platform
- Sostituisci l'utilizzo dell'NDB di App Engine con Cloud NDB (vedi anche il Modulo 2)
- Configura diversi provider di identità di autenticazione utilizzando Firebase Auth
- Usa l'API Cloud Resource Manager per ottenere informazioni IAM del progetto
- Utilizzare l'SDK Admin Firebase per ottenere informazioni sugli utenti
- Porta l'applicazione di esempio in Python 3
Che cosa ti serve
- Un progetto piattaforma Google Cloud con un account di fatturazione Google Cloud attivo
- Competenze Python di base
- Conoscenza pratica dei comandi Linux più comuni
- Conoscenza di base dello sviluppo e del deployment delle app App Engine
- Un'app di esempio di App Engine con Modulo 20 funzionante
Sondaggio
Come utilizzerai questo tutorial?
Come valuteresti la tua esperienza con Python?
Come giudichi la tua esperienza di utilizzo dei servizi Google Cloud?
2. Sfondo
Il servizio Utenti di App Engine è un sistema di autenticazione utente per l'utilizzo da parte delle app di App Engine. Offre Accedi con Google come provider di identità, fornisce pratici link di accesso e disconnessione da utilizzare nelle app e supporta il concetto di utenti amministratori e di funzionalità riservate agli amministratori. Per migliorare la portabilità delle applicazioni, Google Cloud consiglia di eseguire la migrazione dai servizi legacy in bundle di App Engine ai servizi Cloud autonomi, ad esempio dal servizio Utenti a Cloud Identity Platform.
Identity Platform si basa su Firebase Authentication e aggiunge numerose funzionalità aziendali, tra cui l'autenticazione a più fattori, OIDC e Supporto del servizio SSO basato su SAML, multi-tenancy, SLA del 99, 95% e altro ancora. Queste differenze sono evidenziate anche nella pagina di confronto tra i prodotti Identity Platform e Firebase Authentication. Entrambi i prodotti hanno molte più funzioni rispetto a quelle fornite dal servizio Utenti.
Questo codelab del modulo 21 illustra il passaggio dall'autenticazione utente dell'app dal servizio utenti alle funzionalità di Identity Platform che rispecchiano meglio la funzionalità dimostrata nel modulo 20. Il modulo 21 include anche una migrazione dall'NDB di App Engine a Cloud NDB per l'accesso a Datastore, che ripete la migrazione del Modulo 2.
Mentre il codice del Modulo 20 è "pubblicizzato", Come app di esempio Python 2, l'origine stessa è compatibile con Python 2 e 3 e rimane tale anche dopo la migrazione a Identity Platform (e Cloud NDB) qui nel Modulo 21. È possibile continuare a utilizzare il servizio Utenti durante l'upgrade a Python 3, poiché la migrazione a Identity Platform è facoltativa. Consulta il codelab del Modulo 17 e il video per scoprire come continuare a utilizzare i servizi in bundle durante l'upgrade a runtime di seconda generazione come Python 3.
Questo tutorial illustra i seguenti passaggi:
- Configurazione/pre-lavoro
- Aggiorna configurazione
- Modifica il codice dell'applicazione
3. Configurazione/pre-lavoro
In questa sezione viene spiegato come:
- Configura il progetto Cloud
- Ottieni app di esempio di riferimento
- (Ri)Esegui il deployment e convalida l'app di riferimento
- Abilita nuovi servizi/API Google Cloud
Questi passaggi assicurano di iniziare con un codice funzionante pronto per la migrazione a servizi Cloud autonomi.
1. Configura il progetto
Se hai completato il codelab del modulo 20, riutilizza lo stesso progetto (e lo stesso codice). In alternativa, crea un nuovo progetto o riutilizza un altro progetto esistente. Assicurati che il progetto abbia un account di fatturazione attivo e un'app App Engine abilitata. Trova il tuo ID progetto e tienilo a portata di mano durante questo codelab e utilizzalo ogni volta che incontri la variabile PROJ_ID
.
2. Ottieni app di esempio di riferimento
Uno dei prerequisiti è un'app App Engine con modulo 20 funzionante, quindi completa il codelab (consigliato; link riportato sopra) oppure copia il codice del modulo 20 dal repository. Che tu utilizzi il tuo o il nostro, questo è il punto in cui inizieremo ("START"). Questo codelab ti guiderà attraverso la migrazione, concludendo con un codice simile a quello presente nella cartella dei repository del modulo 21 ("FINISH").
- AVVIA: cartella del modulo 20 (Python 2)
- FINISH: Cartelle del modulo 21 ( Python 2 o Python 3)
- Intero repository (per clonare o scaricare il file ZIP)
Copia la cartella di repository del modulo 20. Dovrebbe essere simile all'output seguente e se hai seguito il codelab del Modulo 20, potrebbe avere una cartella lib
:
$ ls README.md appengine_config.py templates app.yaml main.py requirements.txt
3. (Ri)Esegui il deployment e convalida l'app di riferimento
Esegui questi passaggi per eseguire il deployment dell'app del Modulo 20:
- Elimina la cartella
lib
, se presente, ed eseguipip install -t lib -r requirements.txt
per ricompilarla. Potresti dover utilizzarepip2
se hai installato sia Python 2 che 3. - Assicurati di aver installato e iniziato lo strumento a riga di comando
gcloud
e di averne controllato il utilizzo. - Se non vuoi inserire il valore
PROJ_ID
a ogni comandogcloud
eseguito, imposta prima il progetto Cloud congcloud config set project
PROJ_ID
. - Esegui il deployment dell'app di esempio con
gcloud app deploy
- Verifica che l'app venga eseguita come previsto senza errori. Se hai completato il codelab del Modulo 20, l'app mostra le informazioni di accesso dell'utente (email dell'utente, eventuale "badge amministratore" e pulsante di accesso/uscita) in alto insieme alle visite più recenti (illustrate di seguito).
Se viene eseguito l'accesso come utente normale, vengono visualizzati l'indirizzo email dell'utente e la pagina "Accesso" il pulsante diventa "Esci" Pulsante:
Quando si esegue l'accesso come utente amministratore, l'indirizzo email dell'utente viene visualizzato insieme a "(amministratore)" accanto:
4. Abilita nuove API/servizi Google Cloud
Introduzione
L'app Module 20 utilizza le API NDB e Users di App Engine, servizi in bundle che non richiedono una configurazione aggiuntiva, al contrario dei servizi Cloud autonomi. Inoltre, l'app aggiornata impiegherà sia Cloud Identity Platform che Cloud Datastore (tramite la libreria client di Cloud NDB). Inoltre, la nostra necessità di determinare gli utenti amministratori di App Engine richiede anche l'utilizzo dell'API Cloud Resource Manager.
Costo
- App Engine e Cloud Datastore dispongono di " Always Free" e, se rimani al di sotto di questi limiti, non ti viene addebitato alcun costo per il completamento di questo tutorial. Per ulteriori dettagli, vedi anche la pagina dei prezzi di App Engine e la pagina dei prezzi di Cloud Datastore.
- L'utilizzo di Cloud Identity Platform viene fatturato in base al numero di utenti attivi mensili (MAU) o alle verifiche dell'autenticazione; una versione di "senza costi" è disponibile per ogni modello di utilizzo. Per ulteriori dettagli, consulta la pagina dei prezzi. Inoltre, anche se App Engine e Cloud Datastore richiedono la fatturazione, l'utilizzo di GCIP da solo non richiede l'abilitazione della fatturazione, a condizione che non vengano superate le quote giornaliere senza strumenti, quindi considera questa scelta per i progetti Cloud che non prevedono API/servizi Cloud richiesti per la fatturazione.
- L'utilizzo dell'API Cloud Resource Manager è per la maggior parte senza costi in base alla relativa pagina dei prezzi.
Gli utenti possono abilitare le API Cloud dalla console Cloud o dalla riga di comando (tramite il comando gcloud
, incluso in Cloud SDK), a seconda delle preferenze. Iniziamo con le API Cloud Datastore e Cloud Resource Manager.
Dalla console Cloud
Nella console Cloud, vai alla pagina Libreria del gestore API (relativa al progetto corretto) e cerca un'API utilizzando la barra di ricerca.
Abilita queste API:
Individua e fai clic sul pulsante Abilita per ogni API separatamente: ti potrebbero essere richiesti i dati di fatturazione. Ad esempio, questa è la pagina dell'API Resource Manager:
Il pulsante diventa Gestisci una volta attivato (generalmente dopo qualche secondo):
Abilita Cloud Datastore nello stesso modo:
Dalla riga di comando
Sebbene sia visivamente informativo per abilitare le API dalla console, alcuni preferiscono la riga di comando. Avrai il vantaggio aggiuntivo di poter abilitare un numero qualsiasi di API contemporaneamente. Esegui questo comando per abilitare le API Cloud Datastore e Cloud Resource Manager e attendi il completamento dell'operazione, come illustrato qui:
$ gcloud services enable cloudresourcemanager.googleapis.com datastore.googleapis.com Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Ti potrebbero essere richiesti i dati di fatturazione.
La sezione "URL" per ogni API utilizzata nel comando precedente sono chiamati nomi di servizio API e si trovano nella parte inferiore della pagina della libreria per ciascuna API. Se vuoi abilitare altre API Cloud per le tue app, puoi trovare i nomi dei rispettivi servizi nelle pagine delle API corrispondenti. Questo comando elenca tutti i nomi dei servizi per le API che puoi abilitare:
gcloud services list
--available --filter="name:googleapis.com"
.
Sia nella console Cloud che dalla riga di comando, una volta completati i passaggi precedenti, il nostro campione è ora in grado di accedere a queste API. I passaggi successivi consistono nell'abilitazione di Cloud Identity Platform e apportare le modifiche necessarie al codice.
Abilita e configura Cloud Identity Platform (solo console Cloud)
Cloud Identity Platform è un servizio di Marketplace perché si connette o dipende da una risorsa esterna a Google Cloud, ad esempio Firebase Authentication. Al momento, puoi abilitare i servizi di Marketplace solo dalla console Cloud. Procedi nel seguente modo:
- Vai alla pagina Cloud Identity Platform in Cloud Marketplace e fai clic sul pulsante Abilita. Se richiesto, esegui l'upgrade da Firebase Authentication per sbloccare funzionalità aggiuntive, come quelle descritte in precedenza nella sezione Informazioni generali. Ecco la pagina Marketplace in cui è evidenziato il pulsante Attiva:
- Una volta abilitata Identity Platform, potresti essere reindirizzato automaticamente alla pagina Provider di identità. In caso contrario, utilizza questo pratico link per accedervi.
- Attiva il provider di autenticazione Google. Se non è stato configurato alcun provider, fai clic su Add a provider (Aggiungi un provider) e seleziona Google. Quando torni in questa schermata, dovrebbe essere attiva la voce Google. Google è l'unico provider di autenticazione che utilizziamo in questo tutorial per eseguire il mirroring del servizio Utenti di App Engine come un servizio Accedi con Google di base. Nelle tue app puoi attivare provider di autenticazione aggiuntivi.
- Dopo aver selezionato e configurato Google e altri provider di autenticazione desiderati, fai clic su Dettagli di configurazione applicazione e, nella finestra di dialogo di verifica, copia
apiKey
eauthDomain
nell'oggettoconfig
sulla scheda web e salvali entrambi in un luogo sicuro. Perché non copiarli tutti? Lo snippet in questa finestra di dialogo è codificato e datato, quindi salva le parti più importanti e utilizzale nel nostro codice con un maggiore utilizzo simultaneo di Firebase Auth. Dopo aver copiato i valori e averli salvati in un luogo sicuro, fai clic sul pulsante Chiudi per completare la configurazione necessaria.
4. Aggiorna configurazione
Gli aggiornamenti della configurazione includono la modifica di vari file di configurazione e la creazione dell'equivalente di App Engine, ma all'interno dell'ecosistema di Cloud Identity Platform.
appengine_config.py
- Se esegui l'upgrade a Python 3, elimina
appengine_config.py
- Se prevedi di eseguire la modernizzazione a Identity Platform, ma rimanere su Python 2, non eliminare il file. Lo aggiorneremo in seguito durante il backport di Python 2.
requirements.txt
Il file requirements.txt
del modulo 20 riportava solo Flask. Per il modulo 21, aggiungi i seguenti pacchetti:
I contenuti di requirements.txt
ora dovrebbero avere il seguente aspetto:
flask
google-auth
google-cloud-ndb
google-cloud-resource-manager
firebase-admin
app.yaml
- Eseguire l'upgrade a Python 3 significa semplificare il file
app.yaml
. Rimuovi tutto tranne l'istruzione runtime e impostala su una versione attualmente supportata di Python 3. Attualmente nell'esempio viene utilizzata la versione 3.10. - Se continui a utilizzare Python 2, non fare ancora nulla qui.
PRIMA:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
L'app di esempio Modulo 20 non ha gestori di file statici. Se le le tue app lo fanno, lasciale invariate. Se vuoi, puoi rimuovere tutti i gestori di script o lasciarli lì come riferimento, purché ne modifichi gli handle in auto
, come descritto nella guida alla migrazione di app.yaml
. Con queste modifiche, il valore app.yaml
aggiornato per Python 3 è stato semplificato e:
DOPO:
runtime: python310
Altri aggiornamenti della configurazione
Sia che resti su Python 2 o che tu esegua la porta su Python 3, se hai una cartella lib
, eliminala.
5. Modifica il codice dell'applicazione
Questa sezione presenta gli aggiornamenti al file dell'applicazione principale, main.py
, che sostituiscono l'uso del servizio Utenti di App Engine con Cloud Identity Platform. Dopo aver aggiornato l'applicazione principale, aggiorni il modello web templates/index.html
.
Aggiorna importazioni e inizializzazione
Segui questi passaggi per aggiornare le importazioni e inizializzare le risorse dell'applicazione:
- Per le importazioni, sostituisci NDB di App Engine con Cloud NDB.
- Insieme a Cloud NDB, importa anche Cloud Resource Manager.
- Identity Platform si basa su Firebase Auth, quindi importa l'SDK Firebase Admin.
- Le API Cloud richiedono l'utilizzo di un client API, quindi avvialo per Cloud NDB appena sotto l'inizializzazione di Flask.
Durante l'importazione del pacchetto Cloud Resource Manager, lo utilizzeremo in una fase successiva dell'inizializzazione dell'app. Di seguito sono riportate le importazioni e l'inizializzazione dal modulo 20, seguite dall'aspetto delle sezioni dopo l'implementazione delle modifiche precedenti:
PRIMA:
from flask import Flask, render_template, request
from google.appengine.api import users
from google.appengine.ext import ndb
app = Flask(__name__)
DOPO:
from flask import Flask, render_template, request
from google.auth import default
from google.cloud import ndb, resourcemanager
from firebase_admin import auth, initialize_app
# initialize Flask and Cloud NDB API client
app = Flask(__name__)
ds_client = ndb.Client()
Assistenza per gli utenti amministratori di App Engine
Sono due i componenti da aggiungere all'app che supportano il riconoscimento degli utenti amministratori:
_get_gae_admins()
: combina un insieme di utenti amministratore; una volta chiamato e salvatois_admin()
: controlla se l'utente che ha eseguito l'accesso è un utente amministratore. chiamato a qualsiasi accesso utente
La funzione di utilità, _get_gae_admins()
, chiama l'API Resource Manager per recuperare l'elemento allow-policy di Cloud IAM corrente. Il criterio allow-policy definisce e applica i ruoli concessi a determinate entità (utenti umani, account di servizio e così via). La configurazione include:
- Recupero dell'ID progetto Cloud (
PROJ_ID
) - Creazione di un client API Resource Manager (
rm_client
) - Creazione di un insieme (di sola lettura) di ruoli di amministratore App Engine (
_TARGETS
)
Resource Manager richiede l'ID progetto Cloud, quindi importa google.auth.default()
e chiama questa funzione per ottenere l'ID progetto. Questa chiamata presenta un parametro che appare come un URL, ma che è un ambito di autorizzazione OAuth2. Quando esegui app nel cloud, ad esempio su una VM di Compute Engine o un'app App Engine, viene fornito un account di servizio predefinito che dispone di ampi privilegi. In linea con la best practice del privilegio minimo, ti consigliamo di creare account di servizio gestiti dall'utente personali.
Per le chiamate API, è preferibile ulteriore ridurre l'ambito delle app al livello minimo necessario per funzionare correttamente. La chiamata all'API Resource Manager che effettueremo è get_iam_policy()
, che richiede uno dei seguenti ambiti per l'operatività:
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/cloud-platform.read-only
https://www.googleapis.com/auth/cloudplatformprojects
https://www.googleapis.com/auth/cloudplatformprojects.readonly
L'app di esempio richiede solo l'accesso di sola lettura al criterio allow. Non modifica il criterio né richiede l'accesso all'intero progetto. Ciò significa che l'app non ha bisogno di nessuna delle prime tre autorizzazioni necessarie. L'ultima opzione è tutto ciò che serve ed è quella che stiamo implementando per l'app di esempio.
Il corpo principale della funzione crea un insieme vuoto di utenti amministratore (admins
), recupera allow_policy
tramite get_iam_policy()
ed esegue il loop di tutte le associazioni cercando specificatamente i ruoli Amministratore di App Engine:
roles/viewer
roles/editor
roles/owner
roles/appengine.appAdmin
Per ogni ruolo target trovato, vengono combinati gli utenti che appartengono a quel ruolo, aggiungendoli all'insieme complessivo di utenti amministratori. Termina la restituzione di tutti gli utenti amministratori trovati e memorizzati nella cache come costante (_ADMINS
) per l'intera durata di questa istanza App Engine. Vedrai quella chiamata tra poco.
Aggiungi la seguente definizione di funzione _get_gae_admins()
a main.py
appena sotto, creando un'istanza del client API Cloud NDB (ds_client
):
def _get_gae_admins():
'return set of App Engine admins'
# setup constants for calling Cloud Resource Manager API
_, PROJ_ID = default( # Application Default Credentials and project ID
['https://www.googleapis.com/auth/cloudplatformprojects.readonly'])
rm_client = resourcemanager.ProjectsClient()
_TARGETS = frozenset(( # App Engine admin roles
'roles/viewer',
'roles/editor',
'roles/owner',
'roles/appengine.appAdmin',
))
# collate users who are members of at least one GAE admin role (_TARGETS)
admins = set() # set of all App Engine admins
allow_policy = rm_client.get_iam_policy(resource='projects/%s' % PROJ_ID)
for b in allow_policy.bindings: # bindings in IAM allow-policy
if b.role in _TARGETS: # only look at GAE admin roles
admins.update(user.split(':', 1).pop() for user in b.members)
return admins
Quando gli utenti accedono all'app, si verifica quanto segue:
- Dopo che un utente ha eseguito l'accesso a Firebase, viene eseguito un rapido controllo del modello web.
- Quando lo stato di autenticazione cambia nel modello, viene effettuata una chiamata
fetch()
in stile Ajax a/is_admin
il cui gestore è la funzione successiva,is_admin()
. - Il token ID Firebase viene passato nel corpo del POST a
is_admin()
, che lo estrae dalle intestazioni e chiama l'SDK Admin Firebase per la convalida. Se si tratta di un utente valido, estrai il suo indirizzo email e controlla se si tratta di un utente amministratore. - Il risultato booleano viene quindi restituito al modello come 200 riuscito.
Aggiungi is_admin()
a main.py
subito dopo _get_gae_admins()
:
@app.route('/is_admin', methods=['POST'])
def is_admin():
'check if user (via their Firebase ID token) is GAE admin (POST) handler'
id_token = request.headers.get('Authorization')
email = auth.verify_id_token(id_token).get('email')
return {'admin': email in _ADMINS}, 200
Tutto il codice di entrambe le funzioni è necessario per replicare la funzionalità disponibile dal servizio Users, in particolare la sua funzione is_current_user_admin()
. Questa chiamata di funzione nel modulo 20 ha fatto tutto il lavoro pesante, a differenza del modulo 21 in cui implementiamo una soluzione sostitutiva. La buona notizia è che l'app non dipende più da un servizio solo App Engine, il che significa che puoi spostare le tue app in Cloud Run o in altri servizi. Inoltre, puoi modificare la definizione di "utente amministratore" per le tue app semplicemente passando ai ruoli desiderati in _TARGETS
, mentre il servizio Utenti è impostato come hardcoded per i ruoli di amministratore di App Engine.
Inizializza Firebase Auth e memorizza nella cache gli utenti amministratori di App Engine
Avremmo potuto inizializzare Firebase Auth in alto, vicino allo stesso punto in cui è stata inizializzata l'app Flask e in cui è stato creato il client API Cloud NDB, ma non c'è stato bisogno di farlo fino a quando non è stato definito tutto il codice amministratore, che è dove siamo ora. Allo stesso modo, ora che hai definito _get_gae_admins()
, chiamalo per memorizzare nella cache l'elenco degli utenti amministratori.
Aggiungi queste righe subito sotto il corpo della funzione di is_admin()
:
# initialize Firebase and fetch set of App Engine admins
initialize_app()
_ADMINS = _get_gae_admins()
Consulta gli aggiornamenti del modello dei dati
Il modello dei dati Visit
rimane invariato. L'accesso al datastore richiede l'uso esplicito del gestore di contesto del client API Cloud NDB, ds_client.context()
. Nel codice, questo significa che devi aggregare le chiamate Datastore in store_visit()
e fetch_visits()
all'interno dei blocchi with
Python. Questo aggiornamento è identico al modulo 2. Apporta le modifiche come segue:
PRIMA:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
DOPO:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return Visit.query().order(-Visit.timestamp).fetch(limit)
Sposta la logica di accesso degli utenti nel modello web
Il servizio Utenti di App Engine è lato server, mentre Firebase Auth e Cloud Identity Platform sono prevalentemente lato client. Di conseguenza, gran parte del codice per la gestione degli utenti nell'app del modulo 20 passa al modello web del modulo 21.
In main.py
, il contesto web trasmette al modello cinque dati essenziali, i primi quattro elencati sono collegati alla gestione utenti e differiscono a seconda che l'utente abbia eseguito o meno l'accesso:
who
: indirizzo email dell'utente se ha eseguito l'accesso o in caso contrarioadmin
: badge (amministratore) se l'utente che ha eseguito l'accesso è un amministratoresign
: mostra il pulsante Accedi o Escilink
: link di accesso o uscita facendo clic sul pulsantevisits
: visite più recenti
PRIMA:
@app.route('/')
def root():
'main application (GET) handler'
store_visit(request.remote_addr, request.user_agent)
visits = fetch_visits(10)
# put together users context for web template
user = users.get_current_user()
context = { # logged in
'who': user.nickname(),
'admin': '(admin)' if users.is_current_user_admin() else '',
'sign': 'Logout',
'link': '/_ah/logout?continue=%s://%s/' % (
request.environ['wsgi.url_scheme'],
request.environ['HTTP_HOST'],
), # alternative to users.create_logout_url()
} if user else { # not logged in
'who': 'user',
'admin': '',
'sign': 'Login',
'link': users.create_login_url('/'),
}
# add visits to context and render template
context['visits'] = visits # display whether logged in or not
return render_template('index.html', **context)
Tutta la gestione degli utenti passa al modello web, quindi rimangono solo le visite, riportando il gestore principale a quello che avevamo fino al modulo 1 dell'app:
DOPO:
@app.route('/')
def root():
'main application (GET) handler'
store_visit(request.remote_addr, request.user_agent)
visits = fetch_visits(10)
return render_template('index.html', visits=visits)
Aggiorna modello web
Come appaiono nel modello tutti gli aggiornamenti della sezione precedente? Spostando principalmente la gestione utenti dall'app a Firebase Auth in esecuzione nel modello e una porta parziale di tutto il codice che abbiamo spostato in JavaScript. Abbiamo registrato un lieve calo delle main.py
, quindi prevedi una crescita simile nel seguente periodo: templates/index.html
.
PRIMA:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
</head>
<body>
<p>
Welcome, {{ who }} <code>{{ admin }}</code>
<button id="logbtn">{{ sign }}</button>
</p><hr>
<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>
<script>
document.getElementById("logbtn").onclick = () => {
window.location.href = '{{ link }}';
};
</script>
</body>
</html>
Sostituisci l'intero modello web con i contenuti seguenti:
DOPO:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<script type="module">
// import Firebase module attributes
import {
initializeApp
} from "https://www.gstatic.com/firebasejs/9.10.0/firebase-app.js";
import {
GoogleAuthProvider,
getAuth,
onAuthStateChanged,
signInWithPopup,
signOut
} from "https://www.gstatic.com/firebasejs/9.10.0/firebase-auth.js";
// Firebase config:
// 1a. Go to: console.cloud.google.com/customer-identity/providers
// 1b. May be prompted to enable GCIP and upgrade from Firebase
// 2. Click: "Application Setup Details" button
// 3. Copy: 'apiKey' and 'authDomain' from 'config' variable
var firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
};
// initialize Firebase app & auth components
initializeApp(firebaseConfig);
var auth = getAuth();
var provider = new GoogleAuthProvider();
//provider.setCustomParameters({prompt: 'select_account'});
// define login and logout button functions
function login() {
signInWithPopup(auth, provider);
};
function logout() {
signOut(auth);
};
// check if admin & switch to logout button on login; reset everything on logout
onAuthStateChanged(auth, async (user) => {
if (user && user != null) {
var email = user.email;
who.innerHTML = email;
logbtn.onclick = logout;
logbtn.innerHTML = "Logout";
var idToken = await user.getIdToken();
var rsp = await fetch("/is_admin", {
method: "POST",
headers: {Authorization: idToken}
});
var data = await rsp.json();
if (data.admin) {
admin.style.display = "inline";
}
} else {
who.innerHTML = "user";
admin.style.display = "none";
logbtn.onclick = login;
logbtn.innerHTML = "Login";
}
});
</script>
</head>
<body>
<p>
Welcome, <span id="who"></span> <span id="admin"><code>(admin)</code></span>
<button id="logbtn"></button>
</p><hr>
<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>
<script>
var who = document.getElementById("who");
var admin = document.getElementById("admin");
var logbtn = document.getElementById("logbtn");
</script>
</body>
</html>
Il corpo del codice HTML contiene molti componenti, pertanto esaminiamo un elenco alla volta.
Importazioni Firebase
Rimani nell'intestazione del documento HTML e una volta passato il titolo della pagina, importa i componenti Firebase necessari. I componenti di Firebase ora sono suddivisi in più moduli per garantire l'efficienza. Il codice per inizializzare Firebase viene importato dal modulo principale dell'app Firebase, mentre le funzioni che gestiscono Firebase auth, Google come provider di autenticazione, accesso e uscita e stato di autenticazione cambiano "callback" sono tutte importate dal modulo Firebase Auth:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<script type="module">
// import Firebase module attributes
import {
initializeApp
} from "https://www.gstatic.com/firebasejs/9.10.0/firebase-app.js";
import {
GoogleAuthProvider,
getAuth,
onAuthStateChanged,
signInWithPopup,
signOut
} from "https://www.gstatic.com/firebasejs/9.10.0/firebase-auth.js";
Configurazione di Firebase
In precedenza, durante la parte di questo tutorial dedicata alla configurazione di Identity Platform, hai salvato apiKey
e authDomain
dalla finestra di dialogo Dettagli di configurazione applicazione. Aggiungi questi valori alla variabile firebaseConfig
nella sezione successiva. Nei commenti è disponibile un link a ulteriori istruzioni:
// Firebase config:
// 1a. Go to: console.cloud.google.com/customer-identity/providers
// 1b. May be prompted to enable GCIP and upgrade from Firebase
// 2. Click: "Application Setup Details" button
// 3. Copy: 'apiKey' and 'authDomain' from 'config' variable
var firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
};
Inizializzazione di Firebase
La sezione successiva inizializza Firebase con queste informazioni di configurazione.
// initialize Firebase app & auth components
initializeApp(firebaseConfig);
var auth = getAuth();
var provider = new GoogleAuthProvider();
//provider.setCustomParameters({prompt: 'select_account'});
In questo modo viene impostata la possibilità di utilizzare Google come provider di autenticazione e viene fornita un'opzione di commento per mostrare il selettore di account anche se nella sessione del browser è registrato un solo Account Google. In altre parole, quando disponi di più account, ti viene presentato questo "selettore account" come previsto: Tuttavia, se nella sessione è presente un solo utente, la procedura di accesso viene completata automaticamente senza interazione da parte dell'utente. Il popup appare, poi scompare. Puoi forzare la visualizzazione della finestra di dialogo del selettore account per un singolo utente (anziché accedere immediatamente all'app) rimuovendo il commento dalla riga del parametro personalizzato. Se attivati, anche gli accessi di un singolo utente mostrano il selettore dell'account:
Funzioni di accesso e disconnessione
Le righe di codice successive costituiscono le funzioni per i clic sul pulsante di accesso o di disconnessione:
// define login and logout button functions
function login() {
signInWithPopup(auth, provider);
};
function logout() {
signOut(auth);
};
Azioni di accesso e uscita
L'ultima sezione importante di questo blocco <script>
è la funzione che viene richiamata per ogni modifica dell'autorizzazione (accesso o uscita).
// check if admin & switch to logout button on login; reset everything on logout
onAuthStateChanged(auth, async (user) => {
if (user && user != null) {
var email = user.email;
who.innerHTML = email;
logbtn.onclick = logout;
logbtn.innerHTML = "Logout";
var idToken = await user.getIdToken();
var rsp = await fetch("/is_admin", {
method: "POST",
headers: {Authorization: idToken}
});
var data = await rsp.json();
if (data.admin) {
admin.style.display = "inline";
}
} else {
who.innerHTML = "user";
admin.style.display = "none";
logbtn.onclick = login;
logbtn.innerHTML = "Login";
}
});
</script>
</head>
Il codice nel modulo 20 che determina se inviare o meno un "utente che ha eseguito l'accesso" contesto del modello e "utente disconnesso" contesto è stato trasferito qui. Il condizionale in alto genera true
se l'utente ha eseguito l'accesso, attivando le seguenti azioni:
- L'indirizzo email dell'utente è impostato per la visualizzazione.
- Il pulsante Accedi diventa Esci.
- Viene effettuata una chiamata in stile Ajax a
/is_admin
per determinare se mostrare il badge dell'utente amministratore di(admin)
.
Quando l'utente si disconnette, viene eseguita la clausola else
per reimpostare tutte le informazioni dell'utente:
- Nome utente impostato su utente
- Qualsiasi badge amministrativo rimosso
- Il pulsante Esci è stato reimpostato su Accedi
Variabili del modello
Al termine della sezione dell'intestazione, il corpo principale inizia con le variabili del modello che vengono sostituite da elementi HTML che cambiano in base alle esigenze:
- Nome utente visualizzato
- Badge di amministrazione di
(admin)
(se applicabile) - Pulsante Accedi o Esci
<body>
<p>
Welcome, <span id="who"></span> <span id="admin"><code>(admin)</code></span>
<button id="logbtn"></button>
</p><hr>
Visite più recenti e variabili degli elementi HTML
Il codice delle visite più recenti non cambia e il blocco <script>
finale imposta le variabili per gli elementi HTML che cambiano per l'accesso e la disconnessione elencati sopra:
<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>
<script>
var who = document.getElementById("who");
var admin = document.getElementById("admin");
var logbtn = document.getElementById("logbtn");
</script>
</body>
</html>
Questo conclude le modifiche necessarie nell'applicazione e nel modello web per passare dalle API NDB e utente di App Engine a Cloud NDB e Identity Platform, nonché l'upgrade a Python 3. Congratulazioni per aver lanciato la nuova app di esempio del Modulo 21. La nostra versione è disponibile per la revisione nella cartella di repository del Modulo 21b.
La parte successiva del codelab è facoltativa (*) e solo per gli utenti le cui app devono rimanere su Python 2, che ti guiderà attraverso i passaggi necessari per arrivare a un'app Python 2 Modulo 21 funzionante.
6. *Backport Python 2
Questa sezione facoltativa è riservata agli sviluppatori che eseguono una migrazione di Identity Platform, ma che devono continuare a eseguire il runtime Python 2. Se questo non è un problema per te, salta questa sezione.
Per creare una versione Python 2 funzionante dell'app Modulo 21, è necessario quanto segue:
- Requisiti di runtime: file di configurazione che supportano Python 2 e modifiche richieste nell'applicazione principale per evitare incompatibilità con Python 3.
- Modifica di minore entità alla libreria: Python 2 è stato deprecato prima che alcune funzionalità richieste venissero aggiunte alla libreria client di Resource Manager. Di conseguenza, hai bisogno di un modo alternativo per accedere alla funzionalità mancante.
Eseguiamo ora questi passaggi, iniziando dalla configurazione.
Ripristina appengine_config.py
In precedenza in questo tutorial ti abbiamo consigliato di eliminare appengine_config.py
poiché non è utilizzato dal runtime di App Engine di Python 3. Per Python 2, non solo deve essere conservato, ma il Modulo 20 appengine_config.py
deve essere aggiornato per supportare l'uso di librerie di terze parti integrate, ovvero grpcio
e setuptools
. Questi pacchetti sono richiesti ogni volta che la tua app App Engine utilizza librerie client di Cloud come quelle per Cloud NDB e Cloud Resource Manager.
Tra poco aggiungerai questi pacchetti a app.yaml
, ma per consentire l'accesso alla tua app è necessario chiamare la funzione pkg_resources.working_set.add_entry()
di setuptools
. Ciò consente alle librerie di terze parti copiate (in bundle o fornite dal fornitore) installate nella cartella lib
di comunicare con le librerie integrate.
Implementa i seguenti aggiornamenti al tuo file appengine_config.py
per applicare queste modifiche:
PRIMA:
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
Questo codice da solo non è sufficiente a supportare l'utilizzo di setuptools
e grpcio
. Sono necessarie alcune altre righe, quindi aggiorna appengine_config.py
in modo che abbia il seguente aspetto:
DOPO:
import pkg_resources
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
# Add libraries to pkg_resources working set to find the distribution.
pkg_resources.working_set.add_entry(PATH)
Ulteriori dettagli sulle modifiche necessarie per supportare le librerie client di Cloud sono disponibili nella documentazione relativa alla migrazione dei servizi in bundle.
app.yaml
Come per appengine_config.py
, il file app.yaml
deve essere ripristinato a uno che supporti Python 2. Iniziamo con il modulo originale 20 app.yaml
:
PRIMA:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Oltre a setuptools
e grpcio
, come accennato in precedenza, esiste una dipendenza (non esplicitamente correlata alla migrazione di Identity Platform) che richiede l'utilizzo della libreria client di Cloud Storage e che richiede un altro pacchetto integrato di terze parti, ssl
. Aggiungi tutti e tre in una nuova sezione di libraries
, selezionando il "più recente" versioni disponibili di questi pacchetti, in app.yaml
:
DOPO:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: latest
- name: setuptools
version: latest
- name: ssl
version: latest
requirements.txt
Per il modulo 21, abbiamo aggiunto Google Auth, Cloud NDB, Cloud Resource Manager e l'SDK Admin Firebase alla versione requirements.txt
di Python 3. La situazione per Python 2 è più complessa:
- L'API Resource Manager fornisce la funzionalità allow-policy necessaria per l'app di esempio. Purtroppo questo supporto non è ancora disponibile nella versione finale Python 2 della libreria client di Cloud Resource Manager. (È disponibile solo nella versione Python 3).
- Di conseguenza, è necessario un modo alternativo per accedere a questa funzionalità dall'API. La soluzione consiste nell'utilizzare la libreria client delle API di Google di livello inferiore per comunicare con l'API. Per passare a questa libreria client, sostituisci
google-cloud-resource-manager
con il pacchettogoogle-api-python-client
di livello inferiore. - Poiché Python 2 è stato ritirato, il grafico delle dipendenze che supporta il Modulo 21 richiede il blocco di determinati pacchetti a versioni specifiche. Alcuni pacchetti devono essere richiamati anche se non sono specificati nel
app.yaml
di Python 3.
PRIMA:
flask
A partire dal modulo 20 requirements.txt
, aggiornalo come segue per un'app del modulo 21 funzionante:
DOPO:
grpcio==1.0.0
protobuf<3.18.0
six>=1.13.0
flask
google-gax<0.13.0
google-api-core==1.31.1
google-api-python-client<=1.11.0
google-auth<2.0dev
google-cloud-datastore==1.15.3
google-cloud-firestore==1.9.0
google-cloud-ndb
google-cloud-pubsub==1.7.0
firebase-admin
Il pacchetto e i numeri di versione verranno aggiornati nel repository man mano che le dipendenze cambiano, ma questo app.yaml
è sufficiente per un'app funzionante al momento della stesura del presente documento.
Altri aggiornamenti della configurazione
Se non hai eliminato la cartella lib
in precedenza in questo codelab, fallo ora. Con l'aggiornamento requirements.txt
appena aggiornato, esegui questo comando familiare per installare questi requisiti in lib
:
pip install -t lib -r requirements.txt # or pip2
Se sul tuo sistema di sviluppo sono installati sia Python 2 che 3, potrebbe essere necessario utilizzare pip2
anziché pip
.
Modifica il codice dell'applicazione
Fortunatamente, la maggior parte delle modifiche necessarie si trova nei file di configurazione. L'unica modifica necessaria al codice dell'applicazione è un aggiornamento minore che prevede l'utilizzo della libreria client dell'API di Google di livello inferiore anziché la libreria client di Resource Manager per accedere all'API. Non sono richiesti aggiornamenti al modello web templates/index.html
.
Aggiornare le importazioni e l'inizializzazione
Sostituisci la libreria client di Resource Manager (google.cloud.resourcemanager
) con la libreria client delle API di Google (googleapiclient.discovery
), come illustrato di seguito:
PRIMA:
from flask import Flask, render_template, request
from google.auth import default
from google.cloud import ndb, resourcemanager
from firebase_admin import auth, initialize_app
DOPO:
from flask import Flask, render_template, request
from google.auth import default
from google.cloud import ndb
from googleapiclient import discovery
from firebase_admin import auth, initialize_app
Assistenza per gli utenti amministratori di App Engine
Sono necessarie alcune modifiche in _get_gae_admins()
per supportare l'utilizzo della libreria client di livello inferiore. Prima di tutto, parliamo di cosa cambierà e poi ti forniremo tutto il codice da aggiornare.
Il codice Python 2 richiede l'utilizzo sia delle credenziali sia dell'ID progetto restituito da google.auth.default()
. Le credenziali non vengono utilizzate in Python 3, quindi sono state assegnate a una variabile dummy con un trattino basso generico ( _
). Poiché è necessario per la versione Python 2, modifica il trattino basso in CREDS
. Inoltre, anziché creare un client API Resource Manager, creerai un endpoint di servizio API con un concetto simile a un client API, quindi conserveremo lo stesso nome di variabile (rm_client
). Una differenza è che per creare un'istanza di un endpoint di servizio sono necessarie le credenziali (CREDS
).
Queste modifiche sono riflesse nel codice riportato di seguito:
PRIMA:
_, PROJ_ID = default( # Application Default Credentials and project ID
['https://www.googleapis.com/auth/cloudplatformprojects.readonly'])
rm_client = resourcemanager.ProjectsClient()
DOPO:
CREDS, PROJ_ID = default( # Application Default Credentials and project ID
['https://www.googleapis.com/auth/cloud-platform'])
rm_client = discovery.build('cloudresourcemanager', 'v1', credentials=CREDS)
L'altra differenza è che la libreria client di Resource Manager restituisce oggetti allow-policy che utilizzano la notazione puntata-attributo, mentre la libreria client di livello inferiore restituisce i dizionari Python in cui vengono utilizzate le parentesi quadre ( [ ]
). Ad esempio, usa binding.role
per la libreria client di Resource Manager anziché binding['role']
per la libreria di livello inferiore. Il primo utilizza anche "underscore_separated" nomi rispetto alla libreria di livello inferiore che preferisce "CamelCased" più un modo leggermente diverso per passare i parametri API.
Queste differenze di utilizzo sono mostrate di seguito:
PRIMA:
allow_policy = rm_client.get_iam_policy(resource='projects/%s' % PROJ_ID)
for b in allow_policy.bindings: # bindings in IAM allow-policy
if b.role in _TARGETS: # only look at GAE admin roles
admins.update(user.split(':', 1).pop() for user in b.members)
DOPO:
allow_policy = rm_client.projects().getIamPolicy(resource=PROJ_ID).execute()
for b in allow_policy['bindings']: # bindings in IAM allow-policy
if b['role'] in _TARGETS: # only look at GAE admin roles
admins.update(user.split(':', 1).pop() for user in b['members'])
Combinando tutte queste modifiche, sostituisci Python 3 _get_gae_admins()
con questa versione Python 2 equivalente:
def _get_gae_admins():
'return set of App Engine admins'
# setup constants for calling Cloud Resource Manager API
CREDS, PROJ_ID = default( # Application Default Credentials and project ID
['https://www.googleapis.com/auth/cloud-platform'])
rm_client = discovery.build('cloudresourcemanager', 'v1', credentials=CREDS)
_TARGETS = frozenset(( # App Engine admin roles
'roles/viewer',
'roles/editor',
'roles/owner',
'roles/appengine.appAdmin',
))
# collate users who are members of at least one GAE admin role (_TARGETS)
admins = set() # set of all App Engine admins
allow_policy = rm_client.projects().getIamPolicy(resource=PROJ_ID).execute()
for b in allow_policy['bindings']: # bindings in IAM allow-policy
if b['role'] in _TARGETS: # only look at GAE admin roles
admins.update(user.split(':', 1).pop() for user in b['members'])
return admins
La funzione is_admin()
non richiede aggiornamenti perché si basa su _get_gae_admins()
che è già stato aggiornato.
Con questo si concludono le modifiche necessarie per il backporting dell'app Python 3 Modulo 21 in Python 2. Congratulazioni per aver scaricato l'app di esempio aggiornata del Modulo 21. Troverai tutto il codice nella cartella di repository del Modulo 21a.
7. Riepilogo/Pulizia
Gli ultimi passaggi nel codelab sono garantire che le entità (utenti o account di servizio) che eseguono questa app abbiano le autorizzazioni appropriate, poi eseguire il deployment dell'app per confermare che funzioni come previsto e le modifiche si riflettono nell'output.
Può leggere i criteri di autorizzazione IAM
In precedenza ti abbiamo illustrato i quattro ruoli necessari per essere riconosciuti come utente amministratore di App Engine, ma ora c'è un quinto ruolo con cui acquisire familiarità:
roles/viewer
roles/editor
roles/owner
roles/appengine.appAdmin
roles/resourcemanager.projectIamAdmin
(per le entità che accedono al criterio di autorizzazione IAM)
Il ruolo roles/resourcemanager.projectIamAdmin
consente alle entità di determinare se un utente finale è membro di uno dei ruoli amministrativi di App Engine. Senza l'appartenenza a roles/resourcemanager.projectIamAdmin
, le chiamate all'API Cloud Resource Manager per ottenere il criterio di autorizzazione non andranno a buon fine.
Non devi intraprendere alcuna azione esplicita qui, perché la tua app verrà eseguita nell'account di servizio predefinito di App Engine, a cui viene automaticamente concessa l'appartenenza a questo ruolo. Anche se utilizzi l'account di servizio predefinito durante la fase di sviluppo, ti consigliamo vivamente di creare e utilizzare un account di servizio gestito dall'utente con le autorizzazioni minime necessarie per il corretto funzionamento dell'app. Per concedere l'iscrizione a un account di servizio di questo tipo, esegui questo comando:
$ gcloud projects add-iam-policy-binding PROJ_ID --member="serviceAccount:USR_MGD_SVC_ACCT@PROJ_ID.iam.gserviceaccount.com" --role=roles/resourcemanager.projectIamAdmin
PROJ_ID
è l'ID progetto Cloud e USR_MGD_SVC_ACCT@PROJ_ID.iam.gserviceaccount.com
è l'account di servizio gestito dall'utente che crei per la tua app. Questo comando restituisce il criterio IAM aggiornato per il progetto, dove puoi confermare che l'account di servizio è membro di roles/resourcemanager.projectIamAdmin
. Per ulteriori informazioni, consulta la documentazione di riferimento. Per ripetere l'operazione, non è necessario emettere questo comando in questo codelab, ma salvalo come riferimento per la modernizzazione delle tue app.
Esegui il deployment e verifica l'applicazione
Carica la tua app nel cloud con il comando gcloud app deploy
standard. Una volta eseguito il deployment, dovresti vedere una funzionalità quasi identica all'app del modulo 20, tranne per il fatto che hai sostituito il servizio Utenti di App Engine con Cloud Identity Platform (e Firebase Auth) per la gestione degli utenti:
Una differenza che noterai rispetto al Modulo 20 è che, se fai clic sull'accesso, viene visualizzato un popup invece di un reindirizzamento, come mostrato in alcuni degli screenshot seguenti. Come nel caso del Modulo 20, tuttavia, il comportamento varia leggermente in base al numero di Account Google registrati con il browser.
Se non ci sono utenti registrati con il browser o un singolo utente che non ha ancora eseguito l'accesso, viene visualizzato un popup Accedi con Google generico:
Se un singolo utente è registrato con il tuo browser, ma esegue l'accesso altrove, non viene visualizzata alcuna finestra di dialogo (oppure si apre e si chiude immediatamente) e l'app passa allo stato di accesso (vengono visualizzati l'email dell'utente e il pulsante Esci).
Alcuni sviluppatori potrebbero voler fornire un selettore account, anche per un singolo utente:
Per implementarlo, rimuovi il commento dalla riga provider.setCustomParameters({prompt: 'select_account'});
nel modello web come descritto in precedenza.
Se ci sono più utenti, viene visualizzata la finestra di dialogo del selettore dell'account (vedi di seguito). Se non ha ancora eseguito l'accesso, all'utente verrà chiesto di farlo. Se hai già eseguito l'accesso, il popup scompare e l'app passa allo stato di accesso.
Lo stato di accesso del modulo 21 è identico a quello dell'interfaccia utente del modulo 20:
Lo stesso vale quando un utente amministratore ha eseguito l'accesso:
A differenza del modulo 21, il modulo 20 accede sempre alla logica per i contenuti del modello web dall'app (codice lato server). Un difetto del Modulo 20 è che una visita viene registrata quando l'utente finale accede all'app per la prima volta, mentre un'altra viene registrata quando un utente esegue l'accesso.
Per il modulo 21, la logica di accesso avviene solo nel modello web (codice lato client). Non è richiesto un trip lato server per determinare quali contenuti visualizzare. L'unica chiamata effettuata al server è la verifica degli utenti amministratore dopo l'accesso di un utente finale. Ciò significa che accessi e disconnessioni non registrano ulteriori visite, pertanto l'elenco delle visite più recenti rimane costante per le azioni di gestione degli utenti. Nota che gli screenshot riportati sopra mostrano lo stesso insieme di quattro visite per più accessi utente.
Gli screenshot del modulo 20 dimostrano il "bug della visita doppia" all'inizio di questo codelab. Log delle visite separati per ogni azione di accesso o uscita. Controlla i timestamp della visita più recente per ogni screenshot che mostra l'ordine cronologico.
Esegui la pulizia
Generale
Se per il momento hai finito, ti consigliamo di disabilitare l'app App Engine per evitare di incorrere in fatturazione. Tuttavia, se desideri eseguire altri test o sperimentarli, la piattaforma App Engine ha una quota senza costi, pertanto, se non superi il livello di utilizzo, non ti verrà addebitato alcun costo. Questo riguarda il computing, ma potrebbero essere addebitati costi anche per i servizi App Engine pertinenti, quindi consulta la pagina dei prezzi per ulteriori informazioni. Se la migrazione coinvolge altri servizi Cloud, questi vengono fatturati separatamente. In entrambi i casi, se applicabile, consulta la sezione "Specifici di questo codelab" di seguito.
Per garantire la piena divulgazione, il deployment su una piattaforma di serverless computing di Google Cloud come App Engine comporta costi minori di build e archiviazione. Cloud Build e Cloud Storage hanno una quota senza costi specifica. Lo spazio di archiviazione dell'immagine esaurisce una parte della quota. Tuttavia, potresti risiedere in una regione che non ha un livello senza costi, quindi tieni presente l'utilizzo dello spazio di archiviazione per ridurre al minimo i costi potenziali. "cartelle" specifiche di Cloud Storage da esaminare includono:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
- I link allo spazio di archiviazione riportati sopra dipendono dalla tua
PROJECT_ID
e dalla tuaLOC
azione, ad esempio "us
" se la tua app è ospitata negli Stati Uniti.
Se invece non intendi continuare con questa applicazione o con altri codelab di migrazione correlati e vuoi eliminare tutto completamente, chiudi il progetto.
Specifico di questo codelab
I servizi elencati di seguito sono esclusivi per questo codelab. Per ulteriori informazioni, fai riferimento alla documentazione di ciascun prodotto:
- Il servizio App Engine Datastore è fornito da Cloud Datastore (Cloud Firestore in modalità Datastore), che prevede anche un livello senza costi; consulta la pagina relativa ai prezzi per ulteriori informazioni.
- L'utilizzo di Cloud Identity Platform prevede un certo livello di a seconda dei servizi che usi. Per ulteriori dettagli, consulta la pagina dei prezzi.
- L'utilizzo dell'API Cloud Resource Manager è per la maggior parte senza costi in base alla relativa pagina dei prezzi.
Passaggi successivi
Oltre a questo tutorial, altri moduli di migrazione che si concentrano sull'abbandono dei servizi in bundle legacy da prendere in considerazione includono:
- Modulo 2: migrazione da App Engine
ndb
a Cloud NDB - Moduli 7-9: migrazione dalla coda di attività di App Engine (attività push) a Cloud Tasks
- Moduli 12-13: migrazione da App Engine Memcache a Cloud Memorystore
- Moduli 15-16: migrazione dal Blobstore di App Engine a Cloud Storage
- Moduli 18-19: migrazione dalla coda di attività di App Engine (attività pull) a Cloud Pub/Sub
App Engine non è più l'unica piattaforma serverless in Google Cloud. Se hai un'app App Engine di piccole dimensioni o con funzionalità limitate e vuoi convertirla in un microservizio autonomo oppure vuoi suddividere un'app monolitica in più componenti riutilizzabili, questi sono ottimi motivi per passare a Cloud Functions. Se la containerizzazione è diventata parte del flusso di lavoro per lo sviluppo delle applicazioni, in particolare se è costituita da una pipeline CI/CD (integrazione continua/distribuzione continua o deployment), valuta la possibilità di eseguire la migrazione a Cloud Run. Questi scenari sono trattati nei seguenti moduli:
- Eseguire la migrazione da App Engine a Cloud Functions: consulta il Modulo 11
- Esegui la migrazione da App Engine a Cloud Run: consulta il Modulo 4 per containerizzare la tua app con Docker oppure il Modulo 5 per eseguire questa operazione senza container, conoscenze di Docker o
Dockerfile
Il passaggio a un'altra piattaforma serverless è facoltativo e prima di apportare modifiche ti consigliamo di valutare le opzioni migliori per le tue app e i tuoi casi d'uso.
Indipendentemente dal modulo di migrazione successivo, sarà possibile accedere a tutti i contenuti di Serverless Migration Station (codelab, video, codice sorgente [se disponibile]) nel relativo repository open source. L'elemento README
del repository fornisce anche indicazioni sulle migrazioni da prendere in considerazione e su eventuali "ordine" pertinenti dei Moduli di migrazione.
8. Risorse aggiuntive
Di seguito sono elencate le risorse aggiuntive per gli sviluppatori che esplorano ulteriormente questo modulo di migrazione o quelli correlati. Di seguito puoi fornire un feedback su questi contenuti, trovare link al codice e vari documenti che potrebbero esserti utili.
Problemi/feedback dei codelab
Se riscontri problemi con questo codelab, cercali prima di procedere con l'invio. Link per eseguire ricerche e creare nuovi problemi:
Risorse di migrazione
I link alle cartelle repository per il modulo 20 (START) e il modulo 21 (FINISH) sono disponibili nella tabella seguente.
Codelab | Python 2 | Python 3 |
(n/d) | ||
Modulo 21 (questo codelab) |
Riferimenti online
Di seguito sono riportate le risorse pertinenti per questo tutorial:
Cloud Identity Platform e Cloud Marketplace
- Pagina del prodotto Identity Platform
- Firebase Authentication
- Pagina di confronto tra i prodotti Identity Platform e Firebase Auth
- Informazioni sui prezzi di Identity Platform
- Quote Platform di Identity Platform (e utilizzo senza strumenti)
- Configurazione dei provider Identity Platform
- Pagina del prodotto Cloud Marketplace
- Pagina Identity Platform in Marketplace
Cloud Resource Manager, Cloud IAM, SDK Firebase Admin
- Pagina del prodotto Resource Manager
- Informazioni sui prezzi di Resource Manager
- Libreria client di Resource Manager
- Panoramica di Cloud IAM (roles, allow-policy e così via)
- SDK Admin Firebase (Python)
Utenti di App Engine, NDB di App Engine, Cloud NDB, Cloud Datastore
- Panoramica degli utenti di App Engine
- Documentazione su App Engine NDB
- Repository NDB di App Engine
- Libreria client di Cloud NDB
- Repository Cloud NDB
- Pagina del prodotto Cloud Datastore
- Informazioni sui prezzi di Cloud Datastore
Altri riferimenti al Modulo di migrazione
- Introduzione al Modulo di migrazione
- Tutte le "Serverless Migration Station"
- Documentazione sulla migrazione a Python 3
- Modulo 17 di migrazione "Utilizzo dei servizi in bundle in runtime di 2a generazione" codelab
- Modulo di migrazione 20 "Aggiungere il servizio utenti App Engine alle app Flask" codelab
Migrazione ad App Engine
- Utilizzo di librerie di terze parti nelle app Python 2
- Modifiche a
app.yaml
nei runtime di 2a generazione (Python 3) - Guida alla migrazione di Cloud NDB
- Contenuti della migrazione Cloud NDB
Piattaforma App Engine
- Documentazione di App Engine
- Runtime Python 2 App Engine (ambiente standard)
- Utilizzo delle librerie integrate di App Engine in App Engine per Python 2
- Runtime Python 3 per App Engine (ambiente standard)
- Differenze tra Python 2 e 3 runtime App Engine (ambiente standard)
- Guida alla migrazione di Python da 2 a 3 per App Engine (ambiente standard)
- Informazioni su prezzi e quote di App Engine
- Lancio della piattaforma App Engine di seconda generazione (2018)
- Confronto tra primo e piattaforme di seconda generazione
- Assistenza a lungo termine per i runtime legacy
- Esempi di migrazione della documentazione
- Esempi di migrazione forniti dalla community
Cloud SDK
- SDK Google Cloud
- Strumento a riga di comando
gcloud
di Cloud SDK - Attivare (e disattivare) le API di Google
- Gestore API Cloud Console (attiva/disattiva API)
- Abilitazione delle API di Google con
gcloud
- Elenco delle API di Google con
gcloud
Altre informazioni sul cloud
- Python su Google Cloud
- Documentazione sulle librerie client Python
- Repository delle librerie client di Python
- " Always Free" livello
- Cloud SDK
- Strumento a riga di comando
gcloud
di Cloud SDK - Tutta la documentazione di Google Cloud
Video
- Stazione di migrazione serverless
- Esplorazioni serverless
- Iscriviti a Google Cloud Tech
- Iscriviti a Google Developers
Licenza
Questo lavoro è concesso in licenza ai sensi di una licenza Creative Commons Attribution 2.0 Generic.