1. Ringkasan
Serangkaian codelab Serverless Migration Station (tutorial praktik mandiri) dan video terkait bertujuan untuk membantu developer serverless Google Cloud memodernisasi aplikasi mereka dengan memandu mereka melalui satu atau beberapa migrasi, terutama beralih dari layanan lama. Dengan melakukannya, aplikasi Anda akan lebih portabel dan Anda akan memiliki lebih banyak opsi dan fleksibilitas, sehingga Anda dapat berintegrasi dengan dan mengakses berbagai produk Cloud serta mengupgrade ke rilis bahasa yang lebih baru dengan lebih mudah. Meskipun awalnya berfokus pada pengguna Cloud paling awal, terutama developer App Engine (lingkungan standar), seri ini cukup luas untuk mencakup platform serverless lainnya seperti Cloud Functions dan Cloud Run, atau di tempat lain jika berlaku.
Tujuan codelab ini adalah untuk menunjukkan kepada developer App Engine Python 2 cara bermigrasi dari App Engine Users API/service ke Cloud Identity Platform (GCIP). Ada juga migrasi implisit dari App Engine NDB ke Cloud NDB untuk akses Datastore (terutama dibahas dalam Modul Migrasi 2) serta upgrade ke Python 3.
Modul 20 membahas cara menambahkan penggunaan Users API ke aplikasi contoh Modul 1. Dalam modul ini, Anda akan mengambil aplikasi Modul 20 yang telah selesai dan memigrasikan penggunaannya ke Cloud Identity Platform.
Anda akan mempelajari cara
- Mengganti penggunaan layanan Pengguna App Engine dengan Cloud Identity Platform
- Ganti penggunaan App Engine NDB dengan Cloud NDB (lihat juga Modul 2)
- Menyiapkan penyedia identitas autentikasi yang berbeda menggunakan Firebase Auth
- Menggunakan Cloud Resource Manager API untuk mendapatkan informasi IAM project
- Menggunakan Firebase Admin SDK untuk mendapatkan informasi pengguna
- Melakukan porting aplikasi contoh ke Python 3
Yang Anda butuhkan
- Project Google Cloud Platform dengan akun penagihan GCP yang aktif
- Keterampilan Python dasar
- Pengetahuan perintah Linux umum yang berfungsi
- Pengetahuan dasar tentang mengembangkan dan men-deploy aplikasi App Engine
- Aplikasi contoh App Engine Modul 20 yang berfungsi
Survei
Bagaimana Anda akan menggunakan tutorial ini?
Bagaimana penilaian Anda terhadap pengalaman dengan Python?
Bagaimana penilaian Anda terhadap pengalaman menggunakan layanan Google Cloud?
2. Latar belakang
Layanan Pengguna App Engine adalah sistem autentikasi pengguna untuk digunakan oleh aplikasi App Engine. Layanan ini menyediakan Login dengan Google sebagai penyedia identitasnya, menyediakan link login dan logout yang mudah digunakan dalam aplikasi, serta mendukung konsep pengguna admin dan fungsi khusus admin. Untuk meningkatkan portabilitas aplikasi, Google Cloud merekomendasikan migrasi dari layanan paket App Engine lama ke layanan mandiri Cloud, misalnya, dari layanan Pengguna ke Cloud Identity Platform, dan lain-lain.
Identity Platform didasarkan pada Firebase Authentication, dan menambahkan sejumlah fitur perusahaan termasuk autentikasi multi-faktor, dukungan SSO OIDC & SAML, multi-tenancy, SLA 99,95%, dan banyak lagi. Perbedaan ini juga ditandai di halaman perbandingan produk Identity Platform dan Firebase Authentication. Kedua produk ini memiliki fitur yang jauh lebih banyak daripada fungsi yang disediakan oleh layanan Pengguna.
Codelab Modul 21 ini menunjukkan cara mengalihkan autentikasi pengguna aplikasi dari layanan Pengguna ke fitur Identity Platform yang paling mirip dengan fungsi yang ditunjukkan di Modul 20. Modul 21 juga menampilkan migrasi dari App Engine NDB ke Cloud NDB untuk akses Datastore, yang mengulangi migrasi Modul 2.
Meskipun kode Modul 20 "diiklankan" sebagai aplikasi contoh Python 2, sumbernya sendiri kompatibel dengan Python 2 dan 3, dan tetap seperti itu bahkan setelah bermigrasi ke Identity Platform (dan Cloud NDB) di Modul 21 ini. Anda dapat terus menggunakan layanan Pengguna saat mengupgrade ke Python 3 karena migrasi ke Identity Platform bersifat opsional. Lihat codelab dan video Modul 17 untuk mempelajari cara terus menggunakan layanan paket saat mengupgrade ke runtime generasi ke-2 seperti Python 3.
Tutorial ini mencakup langkah-langkah berikut:
- Penyiapan/Prakerja
- Update konfigurasi
- Mengubah kode aplikasi
3. Penyiapan/Prakerja
Bagian ini menjelaskan cara:
- Menyiapkan project Cloud
- Dapatkan aplikasi contoh dasar pengukuran
- Deploy (ulang) dan validasi aplikasi dasar pengukuran
- Mengaktifkan layanan/API Google Cloud baru
Langkah-langkah ini memastikan Anda memulai dengan kode yang berfungsi dan siap untuk dimigrasikan ke layanan Cloud mandiri.
1. Siapkan project
Jika Anda sudah menyelesaikan codelab Modul 20, gunakan kembali project (dan kode) yang sama. Atau, buat project baru atau gunakan kembali project lain yang sudah ada. Pastikan project memiliki akun penagihan yang aktif dan aplikasi App Engine yang diaktifkan. Temukan project ID Anda dan siapkan selama codelab ini dan gunakan setiap kali Anda menemukan variabel PROJ_ID.
2. Dapatkan aplikasi contoh dasar pengukuran
Salah satu prasyaratnya adalah aplikasi App Engine Modul 20 yang berfungsi, jadi selesaikan codelabnya (direkomendasikan; link di atas) atau salin kode Modul 20 dari repo. Baik Anda menggunakan kode Anda atau kode kami, di sinilah kita akan memulai ("START"). Codelab ini akan memandu Anda melakukan migrasi, yang diakhiri dengan kode yang menyerupai kode di folder repo Modul 21 ("FINISH").
- START: Folder Module 20 (Python 2)
- FINISH: Folder Modul 21 ( Python 2 atau Python 3)
- Seluruh repo (untuk melakukan clone atau mendownload file ZIP)
Salin folder repositori Modul 20. Output-nya akan terlihat seperti output di bawah, dan mungkin memiliki folder lib jika Anda telah menyelesaikan codelab Modul 20:
$ ls README.md appengine_config.py templates app.yaml main.py requirements.txt
3. Deploy (ulang) dan validasi aplikasi dasar pengukuran
Lakukan langkah-langkah berikut untuk men-deploy aplikasi Module 20:
- Hapus folder
libjika ada dan jalankanpip install -t lib -r requirements.txtuntuk mengisinya kembali. Anda mungkin perlu menggunakanpip2jika telah menginstal Python 2 dan 3. - Pastikan Anda telah menginstal dan menginisialisasi alat command line
gcloudserta meninjau penggunaannya. - Jika Anda tidak ingin memasukkan
PROJ_IDdengan setiap perintahgcloudyang dikeluarkan, tetapkan project Cloud dengangcloud config set projectPROJ_IDterlebih dahulu. - Men-deploy aplikasi contoh dengan
gcloud app deploy - Konfirmasi bahwa aplikasi berjalan seperti yang diharapkan tanpa error. Jika Anda telah menyelesaikan codelab Modul 20, aplikasi akan menampilkan informasi login pengguna (email pengguna, kemungkinan "badge admin", dan tombol login/logout) di bagian atas bersama dengan kunjungan terbaru (diilustrasikan di bawah).

Login sebagai pengguna biasa akan menyebabkan alamat email pengguna ditampilkan, dan tombol "Login" berubah menjadi tombol "Logout":

Login sebagai pengguna admin akan menyebabkan alamat email pengguna ditampilkan bersama dengan "(admin)" di sampingnya:

4. Mengaktifkan API/layanan Google Cloud baru
Pengantar
Aplikasi Module 20 menggunakan App Engine NDB dan Users API, layanan paket yang tidak memerlukan penyiapan tambahan, tetapi layanan Cloud mandiri memerlukannya, dan aplikasi yang diupdate akan menggunakan Cloud Identity Platform dan Cloud Datastore (melalui library klien Cloud NDB). Selain itu, kebutuhan kami untuk menentukan pengguna admin App Engine juga memerlukan penggunaan Cloud Resource Manager API.
Biaya
- App Engine dan Cloud Datastore memiliki kuota paket "Selalu Gratis", dan selama Anda tidak melebihi batas tersebut, Anda tidak akan dikenai biaya untuk menyelesaikan tutorial ini. Lihat juga halaman harga App Engine dan halaman harga Cloud Datastore untuk mengetahui detail selengkapnya.
- Penggunaan Cloud Identity Platform ditagih berdasarkan jumlah pengguna aktif bulanan (MAU) atau verifikasi autentikasi; beberapa versi "gratis" tersedia untuk setiap model penggunaan. Lihat halaman harganya untuk mengetahui detail selengkapnya. Selain itu, meskipun App Engine dan Cloud Datastore memerlukan penagihan, penggunaan GCIP itu sendiri tidak memerlukan pengaktifan penagihan selama Anda tidak melebihi kuota harian tanpa instrumennya, jadi pertimbangkan hal ini untuk project Cloud yang tidak melibatkan API/layanan Cloud yang memerlukan penagihan.
- Penggunaan Cloud Resource Manager API sebagian besar tidak dikenai biaya per halaman harganya.
Pengguna mengaktifkan Cloud API dari konsol Cloud atau dari command line (melalui perintah gcloud, bagian dari Cloud SDK), bergantung pada preferensi Anda. Mari kita mulai dengan Cloud Datastore dan Cloud Resource Manager API.
Dari Cloud Console
Buka halaman Library API Manager (untuk project yang benar) di Konsol Cloud, lalu telusuri API menggunakan kotak penelusuran. 
Aktifkan API berikut:
Temukan dan klik tombol Aktifkan untuk setiap API secara terpisah—Anda mungkin diminta untuk memberikan informasi penagihan. Misalnya, berikut halaman untuk Resource Manager API:

Tombol akan berubah menjadi Kelola setelah diaktifkan (biasanya setelah beberapa detik):

Aktifkan Cloud Datastore dengan cara yang sama:

Dari command line
Meskipun secara visual informatif untuk mengaktifkan API dari konsol, beberapa orang lebih memilih command line. Anda mendapatkan bonus tambahan berupa kemampuan untuk mengaktifkan sejumlah API sekaligus. Keluarkan perintah ini untuk mengaktifkan Cloud Datastore dan Cloud Resource Manager API, lalu tunggu hingga operasi selesai, seperti yang diilustrasikan di sini:
$ gcloud services enable cloudresourcemanager.googleapis.com datastore.googleapis.com Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Anda mungkin akan diminta memasukkan informasi penagihan.
"URL" untuk setiap API yang digunakan dalam perintah di atas disebut nama layanan API, dan dapat ditemukan di bagian bawah halaman pustaka untuk setiap API. Jika ingin mengaktifkan Cloud API lain untuk aplikasi Anda sendiri, Anda dapat menemukan nama layanan masing-masing di halaman API yang sesuai. Perintah ini mencantumkan semua nama layanan untuk API yang dapat Anda aktifkan:
gcloud services list --available --filter="name:googleapis.com".
Baik di Konsol Cloud maupun di command line, setelah Anda menyelesaikan langkah-langkah di atas, sampel kami kini dapat mengakses API tersebut. Langkah berikutnya adalah mengaktifkan Cloud Identity Platform dan membuat perubahan kode yang diperlukan.
Mengaktifkan dan menyiapkan Cloud Identity Platform (khusus Konsol Cloud)
Cloud Identity Platform adalah layanan Marketplace karena terhubung ke atau bergantung pada resource di luar Google Cloud, misalnya, Firebase Authentication. Saat ini, Anda hanya dapat mengaktifkan layanan Marketplace dari Konsol Cloud. Ikuti langkah-langkah di bawah:
- Buka halaman Cloud Identity Platform di Cloud Marketplace, lalu klik tombol Aktifkan di sana. Lakukan upgrade dari Firebase Authentication jika diminta—tindakan ini akan membuka fitur tambahan, seperti yang dijelaskan sebelumnya di bagian Latar Belakang. Berikut halaman Marketplace yang menandai tombol Aktifkan:

- Setelah Identity Platform diaktifkan, Anda dapat otomatis diarahkan ke halaman Penyedia Identitas. Jika tidak, gunakan link praktis ini untuk mengaksesnya.

- Aktifkan penyedia Google Auth. Jika tidak ada penyedia yang telah disiapkan, klik Tambahkan Penyedia, lalu pilih Google. Saat Anda kembali ke layar ini, entri Google akan diaktifkan. Google adalah satu-satunya penyedia autentikasi yang kami gunakan dalam tutorial ini untuk mencerminkan layanan Pengguna App Engine sebagai layanan Login dengan Google yang ringan. Di aplikasi Anda sendiri, Anda dapat mengaktifkan penyedia autentikasi tambahan.
- Setelah Anda memilih dan menyiapkan Google serta penyedia otorisasi lain yang diinginkan, klik Application Setup Details, lalu dari jendela dialog yang muncul, salin
apiKeydanauthDomaindalam objekconfigdi tab Web, lalu simpan keduanya di tempat yang aman. Mengapa tidak menyalin semuanya? Cuplikan dalam dialog ini dikodekan secara permanen dan diberi tanggal, jadi cukup simpan bagian yang paling penting dan gunakan dalam kode kita dengan penggunaan Firebase Auth yang lebih serentak. Setelah Anda menyalin nilai dan menyimpannya di tempat yang aman, klik tombol Tutup untuk menyelesaikan semua penyiapan yang diperlukan.
4. Update konfigurasi
Perubahan konfigurasi mencakup perubahan berbagai file konfigurasi dan pembuatan yang setara dengan App Engine, tetapi dalam ekosistem Cloud Identity Platform.
appengine_config.py
- Jika mengupgrade ke Python 3, hapus
appengine_config.py - Jika berencana memodernisasi ke Identity Platform, tetapi tetap menggunakan Python 2, jangan hapus file tersebut. Sebagai gantinya, kita akan memperbaruinya nanti selama backport Python 2.
requirements.txt
File requirements.txt Modul 20 hanya mencantumkan Flask. Untuk Modul 21, tambahkan paket berikut:
Konten requirements.txt kini akan terlihat seperti ini:
flask
google-auth
google-cloud-ndb
google-cloud-resource-manager
firebase-admin
app.yaml
- Mengupgrade ke Python 3 berarti menyederhanakan file
app.yaml. Hapus semuanya kecuali direktif runtime, dan tetapkan ke versi Python 3 yang saat ini didukung. Contoh saat ini menggunakan versi 3.10. - Jika Anda tetap menggunakan Python 2, jangan lakukan tindakan apa pun di sini.
SEBELUM:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Aplikasi contoh Modul 20 tidak memiliki pengendali file statis. Jika aplikasi Anda melakukannya, biarkan aplikasi tersebut tetap utuh. Anda dapat menghapus semua handler skrip jika diinginkan atau membiarkannya sebagai referensi selama Anda mengubah handle-nya menjadi auto, seperti yang dijelaskan dalam panduan migrasi app.yaml. Dengan perubahan ini, app.yaml yang diperbarui untuk Python 3 disederhanakan menjadi:
SETELAH:
runtime: python310
Pembaruan konfigurasi lainnya
Baik tetap menggunakan Python 2 atau melakukan porting ke Python 3, jika Anda memiliki folder lib, hapus folder tersebut.
5. Mengubah kode aplikasi
Bagian ini menampilkan update pada file aplikasi utama, main.py, yang menggantikan penggunaan layanan Pengguna App Engine dengan Cloud Identity Platform. Setelah mengupdate aplikasi utama, Anda akan mengupdate template web, templates/index.html.
Memperbarui impor dan inisialisasi
Ikuti langkah-langkah di bawah untuk memperbarui impor dan menginisialisasi resource aplikasi:
- Untuk impor, ganti App Engine NDB dengan Cloud NDB.
- Selain Cloud NDB, impor juga Cloud Resource Manager.
- Identity Platform didasarkan pada Firebase Auth, jadi impor Firebase Admin SDK.
- Cloud API memerlukan penggunaan klien API, jadi mulai klien API untuk Cloud NDB tepat di bawah inisialisasi Flask.
Meskipun paket Cloud Resource Manager diimpor di sini, kita akan menggunakannya pada tahap selanjutnya dalam inisialisasi aplikasi. Di bawah ini adalah impor dan inisialisasi dari Modul 20, diikuti dengan tampilan bagian setelah menerapkan perubahan di atas:
SEBELUM:
from flask import Flask, render_template, request
from google.appengine.api import users
from google.appengine.ext import ndb
app = Flask(__name__)
SETELAH:
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()
Dukungan untuk pengguna Admin App Engine
Ada dua komponen yang perlu ditambahkan ke aplikasi yang mendukung pengenalan pengguna admin:
_get_gae_admins()— mengumpulkan kumpulan pengguna admin; dipanggil sekali dan disimpanis_admin()— memeriksa apakah pengguna yang login adalah pengguna admin; dipanggil saat login pengguna mana pun
Fungsi utilitas, _get_gae_admins(), memanggil Resource Manager API untuk mengambil Cloud IAM allow-policy saat ini. Kebijakan izin menentukan dan menerapkan peran yang diberikan kepada akun utama (pengguna manusia, akun layanan, dll.). Penyiapan ini mencakup:
- Mengambil ID project Cloud (
PROJ_ID) - Membuat klien Resource Manager API (
rm_client) - Membuat sekumpulan peran Admin App Engine (hanya baca) (
_TARGETS)
Resource Manager memerlukan ID project Cloud, jadi impor google.auth.default() dan panggil fungsi tersebut untuk mendapatkan ID project. Panggilan tersebut menampilkan parameter yang terlihat seperti URL, tetapi merupakan cakupan izin OAuth2. Saat menjalankan aplikasi di cloud, misalnya, di VM Compute Engine atau aplikasi App Engine, akun layanan default yang memiliki hak istimewa luas akan disediakan. Sesuai dengan praktik terbaik hak istimewa terendah, sebaiknya buat akun layanan yang dikelola pengguna Anda sendiri.
Untuk panggilan API, sebaiknya lebih lanjut kurangi cakupan aplikasi Anda ke tingkat minimum yang diperlukan agar berfungsi dengan baik. Panggilan Resource Manager API yang akan kita lakukan adalah get_iam_policy() yang memerlukan salah satu cakupan berikut untuk beroperasi:
https://www.googleapis.com/auth/cloud-platformhttps://www.googleapis.com/auth/cloud-platform.read-onlyhttps://www.googleapis.com/auth/cloudplatformprojectshttps://www.googleapis.com/auth/cloudplatformprojects.readonly
Aplikasi contoh hanya memerlukan akses hanya baca ke allow-policy. Kebijakan ini tidak mengubah kebijakan dan tidak memerlukan akses ke seluruh project. Artinya, aplikasi tidak memerlukan salah satu dari tiga izin pertama yang diperlukan. Yang terakhir adalah yang diperlukan, dan itulah yang kita terapkan untuk aplikasi contoh.
Bagian utama fungsi membuat set kosong pengguna admin (admins), mengambil allow_policy melalui get_iam_policy(), dan melakukan loop melalui semua bindingnya dengan mencari secara khusus peran Admin App Engine:
roles/viewerroles/editorroles/ownerroles/appengine.appAdmin
Untuk setiap peran target yang ditemukan, skrip ini akan mengumpulkan pengguna yang termasuk dalam peran tersebut, lalu menambahkannya ke keseluruhan kumpulan pengguna admin. Fungsi ini akan berakhir dengan menampilkan semua pengguna admin yang ditemukan dan di-cache sebagai konstanta (_ADMINS) selama masa aktif instance App Engine ini. Kita akan segera melihat panggilan tersebut.
Tambahkan definisi fungsi _get_gae_admins() berikut ke main.py tepat di bawah pembuatan instance klien Cloud NDB API (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
Saat pengguna login ke aplikasi, hal berikut akan terjadi:
- Pemeriksaan cepat dilakukan dari template web setelah pengguna login ke Firebase.
- Saat status autentikasi berubah dalam template, panggilan
fetch()gaya Ajax dilakukan ke/is_adminyang penanganannya adalah fungsi berikutnya,is_admin(). - Token ID Firebase diteruskan di isi POST ke
is_admin(), yang mengambilnya dari header dan memanggil Firebase Admin SDK untuk memvalidasinya. Jika pengguna valid, ekstrak alamat emailnya dan periksa apakah itu adalah pengguna admin. - Hasil Boolean kemudian ditampilkan ke template sebagai 200 yang berhasil.
Tambahkan is_admin() ke main.py tepat setelah _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
Semua kode dari kedua fungsi diperlukan untuk mereplikasi fungsi yang tersedia dari layanan Pengguna, khususnya fungsi is_current_user_admin(). Panggilan fungsi ini di Modul 20 melakukan semua tugas berat, tidak seperti Modul 21 tempat kita menerapkan solusi pengganti. Kabar baiknya adalah aplikasi tidak lagi bergantung pada layanan khusus App Engine, yang berarti Anda dapat memindahkan aplikasi ke Cloud Run atau layanan lainnya. Selain itu, Anda juga dapat mengubah definisi "pengguna admin" untuk aplikasi Anda sendiri hanya dengan beralih ke peran yang diinginkan di _TARGETS, sedangkan layanan Pengguna dikodekan secara permanen untuk peran admin App Engine.
Lakukan inisialisasi Firebase Auth dan simpan pengguna admin App Engine dalam cache
Kita dapat melakukan inisialisasi Firebase Auth di bagian atas dekat tempat yang sama dengan inisialisasi aplikasi Flask dan pembuatan klien Cloud NDB API, tetapi tidak perlu dilakukan hingga semua kode admin ditentukan, yang merupakan posisi kita saat ini. Demikian pula, setelah _get_gae_admins() ditentukan, panggil untuk menyimpan daftar pengguna admin dalam cache.
Tambahkan baris ini tepat di bawah isi fungsi is_admin():
# initialize Firebase and fetch set of App Engine admins
initialize_app()
_ADMINS = _get_gae_admins()
Mengunjungi pembaruan model data
Model data Visit tidak berubah. Akses Datastore memerlukan penggunaan eksplisit pengelola konteks klien Cloud NDB API, ds_client.context(). Dalam kode, ini berarti Anda menggabungkan panggilan Datastore di store_visit() dan fetch_visits() dalam blok with Python. Pembaruan ini sama persis dengan Modul 2. Lakukan perubahan sebagai berikut:
SEBELUM:
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)
SETELAH:
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)
Memindahkan logika login pengguna ke template web
Layanan Pengguna App Engine bersifat sisi server, sedangkan Firebase Auth dan Cloud Identity Platform sebagian besar bersifat sisi klien. Akibatnya, sebagian besar kode pengelolaan pengguna di aplikasi Modul 20 dipindahkan ke template web Modul 21.
Di main.py, konteks web meneruskan lima bagian data penting ke template, empat bagian pertama yang tercantum terkait dengan pengelolaan pengguna dan berbeda bergantung pada apakah pengguna login atau tidak:
who— email pengguna jika login atau pengguna jika tidakadmin— badge (admin) jika pengguna yang login adalah adminsign— menampilkan tombol Login atau Logoutlink— link login atau logout saat tombol diklikvisits— kunjungan terbaru
SEBELUM:
@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)
Semua pengelolaan pengguna dipindahkan ke template web, sehingga kita hanya memiliki kunjungan, yang membawa handler utama kembali ke yang kita miliki di aplikasi Modul 1:
SETELAH:
@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)
Memperbarui template web
Bagaimana tampilan semua pembaruan dari bagian sebelumnya dalam template? Terutama memindahkan pengelolaan pengguna dari aplikasi ke Firebase Auth yang berjalan di template dan port sebagian dari semua kode yang kita pindahkan ke JavaScript. Kami melihat main.py menyusut cukup banyak, jadi kami memperkirakan pertumbuhan serupa di templates/index.html.
SEBELUM:
<!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>
Ganti seluruh template web dengan konten di bawah:
SETELAH:
<!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>
Ada banyak komponen di isi HTML ini, jadi mari kita bahas satu per satu.
Impor Firebase
Saat masih berada di header dokumen HTML, setelah melewati judul halaman, impor komponen Firebase yang diperlukan. Komponen Firebase kini dibagi menjadi beberapa modul untuk efisiensi. Kode untuk menginisialisasi Firebase diimpor dari modul aplikasi Firebase utama, sedangkan fungsi yang mengelola autentikasi Firebase, Google sebagai penyedia autentikasi, login dan logout, serta "callback" perubahan status autentikasi semuanya diimpor dari modul 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";
Konfigurasi Firebase
Sebelumnya selama bagian penyiapan Identity Platform dalam tutorial ini, Anda menyimpan apiKey dan authDomain dari dialog Application Setup Details. Tambahkan nilai tersebut ke variabel firebaseConfig di bagian berikutnya ini. Link ke petunjuk yang lebih mendetail diberikan di komentar:
// 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",
};
Inisialisasi Firebase
Bagian berikutnya akan melakukan inisialisasi Firebase dengan informasi konfigurasi ini.
// initialize Firebase app & auth components
initializeApp(firebaseConfig);
var auth = getAuth();
var provider = new GoogleAuthProvider();
//provider.setCustomParameters({prompt: 'select_account'});
Tindakan ini menetapkan kemampuan untuk menggunakan Google sebagai penyedia autentikasi, dan menyediakan opsi yang dikomentari untuk menampilkan pemilih akun meskipun hanya ada satu akun Google yang terdaftar di sesi browser Anda. Dengan kata lain, saat Anda memiliki beberapa akun, Anda akan melihat "pemilih akun" ini seperti yang diharapkan:
Namun, jika hanya ada satu pengguna dalam sesi, proses login akan selesai secara otomatis tanpa interaksi pengguna. (Pop-up muncul lalu menghilang.) Anda dapat memaksa dialog pemilih akun muncul untuk satu pengguna (vs. langsung login ke aplikasi) dengan menghapus komentar pada baris parameter kustom. Jika diaktifkan, bahkan login pengguna tunggal akan memunculkan pemilih akun: 
Fungsi login dan logout
Baris kode berikutnya membentuk fungsi untuk klik tombol login atau logout:
// define login and logout button functions
function login() {
signInWithPopup(auth, provider);
};
function logout() {
signOut(auth);
};
Tindakan login dan logout
Bagian utama terakhir dalam blok <script> ini adalah fungsi yang dipanggil untuk setiap perubahan autentikasi (login atau logout).
// 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>
Kode di Modul 20 yang menentukan apakah akan mengirim konteks template "pengguna login" atau konteks "pengguna logout" ditransisikan di sini. Kondisional di bagian atas menghasilkan true jika pengguna berhasil login, yang memicu tindakan berikut:
- Alamat email pengguna ditetapkan untuk ditampilkan.
- Tombol Login akan berubah menjadi Logout.
- Panggilan gaya Ajax ke
/is_admindilakukan untuk menentukan apakah badge pengguna admin(admin)akan ditampilkan.
Saat pengguna logout, klausa else akan dieksekusi untuk mereset semua informasi pengguna:
- Nama pengguna ditetapkan ke user
- Badge admin apa pun dihapus
- Tombol Logout berubah kembali menjadi Login
Variabel template
Setelah bagian header berakhir, isi utama dimulai dengan variabel template yang digantikan oleh elemen HTML yang berubah sesuai kebutuhan:
- Nama pengguna yang ditampilkan
- Badge admin
(admin)(jika berlaku) - Tombol Login atau Logout
<body>
<p>
Welcome, <span id="who"></span> <span id="admin"><code>(admin)</code></span>
<button id="logbtn"></button>
</p><hr>
Variabel elemen HTML dan kunjungan terbaru
Kode kunjungan terbaru tidak berubah, dan blok <script> terakhir menetapkan variabel untuk elemen HTML yang berubah untuk login dan logout yang tercantum tepat di atas:
<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>
Dengan demikian, perubahan yang diperlukan dalam aplikasi dan template web untuk beralih dari App Engine NDB dan Users API ke Cloud NDB dan Identity Platform serta mengupgrade ke Python 3 telah selesai. Selamat telah tiba di aplikasi contoh Modul 21 yang baru. Versi kami tersedia untuk ditinjau di folder repo Modul 21b.
Bagian selanjutnya dari codelab ini bersifat opsional (*) dan hanya untuk pengguna yang aplikasinya harus tetap menggunakan Python 2, yang akan memandu Anda melalui langkah-langkah yang diperlukan untuk mendapatkan aplikasi Modul 21 Python 2 yang berfungsi.
6. *Backport Python 2
Bagian opsional ini ditujukan bagi developer yang melakukan migrasi Identity Platform, tetapi harus terus berjalan di runtime Python 2. Jika hal ini tidak menjadi masalah bagi Anda, lewati bagian ini.
Untuk membuat aplikasi Modul 21 versi Python 2 yang berfungsi, Anda memerlukan hal berikut:
- Persyaratan runtime: File konfigurasi yang mendukung Python 2, dan perubahan yang diperlukan dalam aplikasi utama untuk menghindari inkompatibilitas Python 3
- Perubahan kecil pada library: Python 2 tidak digunakan lagi sebelum beberapa fitur yang diperlukan ditambahkan ke library klien Resource Manager. Akibatnya, Anda memerlukan cara alternatif untuk mengakses fungsi yang tidak ada tersebut.
Sekarang kita akan melakukan langkah-langkah tersebut, dimulai dengan konfigurasi.
Pulihkan appengine_config.py
Sebelumnya dalam tutorial ini, Anda dipandu untuk menghapus appengine_config.py karena tidak digunakan oleh runtime Python 3 App Engine. Untuk Python 2, tidak hanya harus dipertahankan, tetapi Module 20 appengine_config.py perlu diupdate untuk mendukung penggunaan library pihak ketiga bawaan, yaitu grpcio dan setuptools. Paket tersebut diperlukan setiap kali aplikasi App Engine Anda menggunakan library klien Cloud seperti library untuk Cloud NDB dan Cloud Resource Manager.
Anda akan menambahkan paket tersebut ke app.yaml sebentar lagi, tetapi agar aplikasi Anda dapat mengaksesnya, fungsi pkg_resources.working_set.add_entry() dari setuptools harus dipanggil. Hal ini memungkinkan library pihak ketiga yang disalin (dipaketkan sendiri atau disediakan vendor) yang diinstal di folder lib dapat berkomunikasi dengan library bawaan.
Terapkan perubahan berikut pada file appengine_config.py Anda untuk menerapkan perubahan ini:
SEBELUM:
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
Kode ini saja tidak cukup untuk mendukung penggunaan setuptools dan grpcio. Beberapa baris lagi diperlukan, jadi perbarui appengine_config.py agar terlihat seperti ini:
SETELAH:
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)
Detail selengkapnya tentang perubahan yang diperlukan untuk mendukung library klien Cloud dapat ditemukan dalam dokumentasi migrasi layanan paket.
app.yaml
Mirip dengan appengine_config.py, file app.yaml harus dikembalikan ke file yang mendukung Python 2. Mari kita mulai dengan Modul 20 app.yaml asli:
SEBELUM:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Selain setuptools dan grpcio seperti yang disebutkan sebelumnya, ada dependensi (tidak secara eksplisit terkait dengan migrasi Identity Platform) yang memerlukan penggunaan library klien Cloud Storage, dan hal tersebut memerlukan paket bawaan pihak ketiga lainnya, ssl. Tambahkan ketiganya di bagian libraries baru, dengan memilih versi "terbaru" dari paket tersebut yang tersedia, ke app.yaml:
SETELAH:
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
Untuk Modul 21, kami menambahkan Google Auth, Cloud NDB, Cloud Resource Manager, dan Firebase Admin SDK ke requirements.txt Python 3. Situasi untuk Python 2 lebih kompleks:
- Resource Manager API menyediakan fungsi kebijakan izin yang diperlukan untuk aplikasi contoh. Sayangnya, dukungan ini belum tersedia di versi akhir Python 2 dari library klien Cloud Resource Manager. (Hanya tersedia di versi Python 3.)
- Oleh karena itu, diperlukan cara alternatif untuk mengakses fitur ini dari API. Solusinya adalah menggunakan library klien Google API level yang lebih rendah untuk berkomunikasi dengan API. Untuk beralih ke library klien ini, ganti
google-cloud-resource-managerdengan paketgoogle-api-python-clienttingkat yang lebih rendah. - Karena Python 2 telah dihentikan, grafik dependensi yang mendukung Modul 21 memerlukan penguncian paket tertentu ke versi tertentu. Beberapa paket harus dipanggil meskipun tidak ditentukan dalam
app.yamlPython 3.
SEBELUM:
flask
Mulai dengan requirements.txt Modul 20, perbarui ke berikut untuk aplikasi Modul 21 yang berfungsi:
SETELAH:
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
Nomor paket dan versi akan diupdate di repo saat dependensi berubah, tetapi app.yaml ini sudah cukup untuk aplikasi yang berfungsi pada saat penulisan ini.
Pembaruan konfigurasi lainnya
Jika Anda belum menghapus folder lib dari bagian awal codelab ini, lakukan sekarang. Dengan requirements.txt yang baru diupdate, jalankan perintah yang sudah dikenal ini untuk menginstal persyaratan ini ke lib:
pip install -t lib -r requirements.txt # or pip2
Jika Anda telah menginstal Python 2 dan 3 di sistem pengembangan, Anda mungkin perlu menggunakan pip2, bukan pip.
Mengubah kode aplikasi
Untungnya, sebagian besar perubahan yang diperlukan ada di file konfigurasi. Satu-satunya perubahan yang diperlukan dalam kode aplikasi adalah update kecil untuk menggunakan library klien Google API tingkat yang lebih rendah, bukan library klien Resource Manager, untuk mengakses API. Tidak ada update yang diperlukan untuk template web templates/index.html.
Memperbarui impor dan inisialisasi
Ganti library klien Resource Manager (google.cloud.resourcemanager) dengan library klien Google API (googleapiclient.discovery), seperti yang diilustrasikan di bawah:
SEBELUM:
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
SETELAH:
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
Dukungan untuk pengguna Admin App Engine
Beberapa perubahan diperlukan di _get_gae_admins() untuk mendukung penggunaan library klien tingkat bawah. Mari kita bahas dulu apa yang berubah, lalu berikan semua kode untuk memperbarui.
Kode Python 2 memerlukan penggunaan kredensial dan project ID yang ditampilkan dari google.auth.default(). Kredensial tidak digunakan di Python 3, sehingga ditetapkan ke variabel dummy garis bawah ( _ ) generik. Karena diperlukan untuk versi Python 2, ubah garis bawah menjadi CREDS. Selain itu, daripada membuat klien Resource Manager API, Anda akan membuat endpoint layanan API, yang konsepnya mirip dengan klien API, sehingga kita tetap menggunakan nama variabel yang sama (rm_client). Salah satu perbedaannya adalah bahwa membuat instance endpoint layanan memerlukan kredensial (CREDS).
Perubahan ini tercermin dalam kode di bawah:
SEBELUM:
_, PROJ_ID = default( # Application Default Credentials and project ID
['https://www.googleapis.com/auth/cloudplatformprojects.readonly'])
rm_client = resourcemanager.ProjectsClient()
SETELAH:
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)
Perbedaan lainnya adalah library klien Resource Manager menampilkan objek allow-policy yang menggunakan notasi atribut bertitik, sedangkan library klien tingkat yang lebih rendah menampilkan kamus Python yang menggunakan tanda kurung siku ( [ ] ), misalnya, gunakan binding.role untuk library klien Resource Manager, bukan binding['role'] untuk library tingkat yang lebih rendah. Yang pertama juga menggunakan nama "underscore_separated" versus library tingkat yang lebih rendah yang lebih memilih nama "CamelCased" ditambah cara yang sedikit berbeda untuk meneruskan parameter API.
Perbedaan penggunaan ini ditunjukkan di bawah:
SEBELUM:
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)
SETELAH:
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'])
Dengan menggabungkan semua perubahan ini, ganti _get_gae_admins() Python 3 dengan versi Python 2 yang setara ini:
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
Fungsi is_admin() tidak memerlukan pembaruan karena bergantung pada _get_gae_admins() yang telah diperbarui.
Dengan demikian, perubahan yang diperlukan untuk mem-backport aplikasi Python 3 Modul 21 ke Python 2 telah selesai. Selamat, Anda telah sampai di aplikasi contoh Modul 21 yang telah diupdate. Anda akan menemukan semua kode di folder repo Modul 21a.
7. Ringkasan/Pembersihan
Langkah terakhir dalam codelab ini adalah memastikan principal (pengguna atau akun layanan) yang menjalankan aplikasi ini memiliki izin yang tepat untuk melakukannya, lalu men-deploy aplikasi Anda untuk mengonfirmasi bahwa aplikasi berfungsi sebagaimana mestinya dan perubahan tercermin dalam output.
Kemampuan untuk membaca kebijakan izin IAM
Sebelumnya, kami telah memperkenalkan empat peran yang diperlukan agar diakui sebagai pengguna admin App Engine, tetapi kini ada peran kelima yang perlu Anda ketahui:
roles/viewerroles/editorroles/ownerroles/appengine.appAdminroles/resourcemanager.projectIamAdmin(untuk akun utama yang mengakses kebijakan izinkan IAM)
Peran roles/resourcemanager.projectIamAdmin memungkinkan akun utama menentukan apakah pengguna akhir adalah anggota dari salah satu peran admin App Engine. Tanpa keanggotaan di roles/resourcemanager.projectIamAdmin, panggilan ke Cloud Resource Manager API untuk mendapatkan kebijakan izinkan akan gagal.
Anda tidak perlu melakukan tindakan eksplisit apa pun di sini karena aplikasi Anda akan berjalan di bawah akun layanan default App Engine yang secara otomatis diberikan keanggotaan dalam peran ini. Meskipun Anda menggunakan akun layanan default selama fase pengembangan, sebaiknya buat dan gunakan akun layanan yang dikelola pengguna dengan izin minimal yang diperlukan agar aplikasi Anda berfungsi dengan benar. Untuk memberikan keanggotaan ke akun layanan tersebut, jalankan perintah berikut:
$ 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 adalah project ID Cloud dan USR_MGD_SVC_ACCT@PROJ_ID.iam.gserviceaccount.com adalah akun layanan yang dikelola pengguna yang Anda buat untuk aplikasi Anda. Perintah ini menampilkan kebijakan IAM yang diperbarui untuk project Anda, tempat Anda dapat mengonfirmasi bahwa akun layanan memiliki keanggotaan di roles/resourcemanager.projectIamAdmin. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi. Sekali lagi, Anda tidak perlu mengeluarkan perintah tersebut dalam codelab ini, tetapi simpan ini sebagai referensi untuk memodernisasi aplikasi Anda sendiri.
Men-deploy dan memverifikasi aplikasi
Upload aplikasi Anda ke cloud dengan perintah gcloud app deploy standar. Setelah di-deploy, Anda akan melihat fungsi yang hampir identik dengan aplikasi Modul 20, kecuali Anda telah berhasil mengganti layanan Pengguna App Engine dengan Cloud Identity Platform (dan Firebase Auth) untuk pengelolaan pengguna:

Satu perbedaan yang akan Anda lihat dibandingkan dengan Modul 20 adalah bahwa mengklik Login akan menampilkan pop-up, bukan pengalihan, yang ditampilkan dalam beberapa screenshot di bawah. Namun, seperti Modul 20, perilakunya sedikit berbeda, bergantung pada jumlah Akun Google yang telah didaftarkan dengan browser.
Jika tidak ada pengguna yang terdaftar dengan browser atau satu pengguna yang belum login, pop-up Login dengan Google generik akan muncul:

Jika satu pengguna terdaftar dengan browser Anda, tetapi login di tempat lain, tidak ada dialog yang muncul (atau dialog muncul dan langsung ditutup), dan aplikasi akan masuk ke status login (menampilkan email pengguna dan tombol Logout).
Beberapa developer mungkin ingin menyediakan pemilih akun, bahkan untuk satu pengguna:

Untuk menerapkannya, hapus komentar pada baris provider.setCustomParameters({prompt: 'select_account'}); di template web seperti yang dijelaskan sebelumnya.
Jika ada beberapa pengguna, dialog pemilih akun akan muncul (lihat di bawah). Jika belum login, pengguna akan diminta untuk login. Jika sudah login, pop-up akan hilang, dan aplikasi akan masuk ke status login.

Status login Modul 21 terlihat identik dengan antarmuka pengguna Modul 20:

Hal yang sama berlaku saat pengguna admin login:

Tidak seperti Modul 21, Modul 20 selalu mengakses logika untuk konten template web dari aplikasi (kode sisi server). Kelemahan Module 20 adalah satu kunjungan dicatat saat pengguna akhir membuka aplikasi untuk pertama kalinya, dan satu kunjungan lainnya dicatat saat pengguna login.
Untuk Modul 21, logika login terjadi hanya di template web (kode sisi klien). Tidak ada perjalanan sisi server yang diperlukan untuk menentukan konten yang akan ditampilkan. Satu-satunya panggilan yang dilakukan ke server adalah pemeriksaan untuk pengguna admin setelah pengguna akhir login. Artinya, login dan logout tidak mencatat kunjungan tambahan, sehingga daftar kunjungan terbaru tetap konstan untuk tindakan pengelolaan pengguna. Perhatikan screenshot di atas yang menampilkan empat kunjungan yang sama di beberapa login pengguna.
Screenshot Modul 20 menunjukkan "bug kunjungan ganda" di awal codelab ini. Log kunjungan terpisah ditampilkan untuk setiap tindakan login atau logout. Periksa stempel waktu kunjungan terbaru untuk setiap screenshot yang menampilkan urutan kronologis.
Pembersihan
Umum
Jika Anda sudah selesai untuk saat ini, sebaiknya nonaktifkan aplikasi App Engine untuk menghindari penagihan. Namun, jika Anda ingin menguji atau bereksperimen lebih lanjut, platform App Engine memiliki kuota gratis, sehingga selama Anda tidak melebihi tingkat penggunaan tersebut, Anda tidak akan dikenai biaya. Biaya tersebut adalah untuk komputasi, tetapi mungkin juga ada biaya untuk layanan App Engine yang relevan, jadi periksa halaman harganya untuk mengetahui informasi selengkapnya. Jika migrasi ini melibatkan layanan Cloud lainnya, layanan tersebut akan ditagih secara terpisah. Dalam kedua kasus tersebut, jika berlaku, lihat bagian "Khusus untuk codelab ini" di bawah.
Untuk pengungkapan penuh, men-deploy ke platform komputasi serverless Google Cloud seperti App Engine akan menimbulkan biaya build dan penyimpanan kecil. Cloud Build memiliki kuota gratisnya sendiri seperti halnya Cloud Storage. Penyimpanan gambar tersebut menggunakan sebagian kuota tersebut. Namun, Anda mungkin tinggal di wilayah yang tidak memiliki paket gratis tersebut, jadi perhatikan penggunaan penyimpanan Anda untuk meminimalkan potensi biaya. "Folder" Cloud Storage tertentu yang harus Anda tinjau meliputi:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- Link penyimpanan di atas bergantung pada
PROJECT_IDdanLOCAnda, misalnya, "us" jika aplikasi Anda dihosting di Amerika Serikat.
Di sisi lain, jika Anda tidak akan melanjutkan aplikasi ini atau codelab migrasi terkait lainnya dan ingin menghapus semuanya, hentikan project Anda.
Khusus untuk codelab ini
Layanan yang tercantum di bawah ini unik untuk codelab ini. Lihat dokumentasi setiap produk untuk mengetahui informasi selengkapnya:
- Layanan App Engine Datastore disediakan oleh Cloud Datastore (Cloud Firestore dalam mode Datastore) yang juga memiliki paket gratis; lihat halaman harganya untuk mengetahui informasi selengkapnya.
- Penggunaan Platform Cloud Identity memiliki tingkat "gratis" tertentu, bergantung pada layanan yang Anda gunakan. Lihat halaman harganya untuk mengetahui detail selengkapnya.
- Penggunaan Cloud Resource Manager API sebagian besar tidak dikenai biaya per halaman harganya.
Langkah berikutnya
Selain tutorial ini, modul migrasi lain yang berfokus pada cara beralih dari layanan paket lama yang perlu dipertimbangkan mencakup:
- Modul 2: bermigrasi dari App Engine
ndbke Cloud NDB - Modul 7-9: melakukan migrasi dari App Engine Task Queue (tugas push) ke Cloud Tasks
- Modul 12-13: bermigrasi dari App Engine Memcache ke Cloud Memorystore
- Modul 15-16: bermigrasi dari Blobstore App Engine ke Cloud Storage
- Modul 18-19: bermigrasi dari App Engine Task Queue (pull task) ke Cloud Pub/Sub
App Engine bukan lagi satu-satunya platform serverless di Google Cloud. Jika Anda memiliki aplikasi App Engine kecil atau aplikasi yang memiliki fungsi terbatas dan ingin mengubahnya menjadi microservice mandiri, atau Anda ingin memecah aplikasi monolitik menjadi beberapa komponen yang dapat digunakan kembali, ini adalah alasan yang baik untuk mempertimbangkan beralih ke Cloud Functions. Jika containerisasi telah menjadi bagian dari alur kerja pengembangan aplikasi Anda, terutama jika terdiri dari pipeline CI/CD (continuous integration/continuous delivery atau deployment), pertimbangkan untuk bermigrasi ke Cloud Run. Skenario ini dibahas dalam modul berikut:
- Bermigrasi dari App Engine ke Cloud Functions: lihat Modul 11
- Melakukan migrasi dari App Engine ke Cloud Run: lihat Modul 4 untuk mem-build aplikasi dalam container dengan Docker, atau Modul 5 untuk melakukannya tanpa container, pengetahuan Docker, atau
Dockerfile
Beralih ke platform serverless lain bersifat opsional, dan sebaiknya pertimbangkan opsi terbaik untuk aplikasi dan kasus penggunaan Anda sebelum melakukan perubahan apa pun.
Terlepas dari modul migrasi mana yang akan Anda pertimbangkan berikutnya, semua konten Serverless Migration Station (codelab, video, kode sumber [jika tersedia]) dapat diakses di repo open source-nya. README repo juga memberikan panduan tentang migrasi mana yang perlu dipertimbangkan dan "urutan" Modul Migrasi yang relevan.
8. Referensi lainnya
Di bawah ini tercantum resource tambahan bagi developer yang mempelajari modul migrasi ini atau yang terkait lebih lanjut. Di bawah ini, Anda dapat memberikan masukan tentang konten ini, menemukan link ke kode, dan berbagai bagian dokumentasi yang mungkin berguna bagi Anda.
Masalah/masukan codelab
Jika Anda menemukan masalah dengan codelab ini, telusuri masalah Anda terlebih dahulu sebelum mengajukan masalah. Link untuk menelusuri dan membuat masalah baru:
Referensi migrasi
Link ke folder repo untuk Modul 20 (START) dan Modul 21 (FINISH) dapat ditemukan pada tabel di bawah.
Codelab | Python 2 | Python 3 |
(T/A) | ||
Modul 21 (codelab ini) |
Referensi online
Berikut adalah referensi yang relevan untuk tutorial ini:
Cloud Identity Platform dan Cloud Marketplace
- Halaman produk Identity Platform
- Firebase Authentication
- Halaman perbandingan produk Identity Platform dan Firebase Auth
- Informasi harga Identity Platform
- Kouta Identity Platform (dan penggunaan tanpa alat)
- Penyiapan penyedia Identity Platform
- Halaman produk Cloud Marketplace
- Halaman Identity Platform di Marketplace
Cloud Resource Manager, Cloud IAM, Firebase Admin SDK
- Halaman produk Resource Manager
- Informasi harga Resource Manager
- Library klien Resource Manager
- Ringkasan Cloud IAM (peran, kebijakan yang diizinkan, dll.)
- Firebase Admin SDK (Python)
Pengguna App Engine, App Engine NDB, Cloud NDB, Cloud Datastore
- Ringkasan App Engine Users
- Dokumen NDB App Engine
- Repo App Engine NDB
- Library klien Cloud NDB
- Repo Cloud NDB
- Halaman produk Cloud Datastore
- Informasi harga Cloud Datastore
Referensi Modul Migrasi Lainnya
- Pengantar Modul Migrasi
- Semua referensi "Serverless Migration Station"
- Dokumentasi migrasi ke Python 3
- Codelab Modul Migrasi 17 "Menggunakan layanan paket dalam runtime generasi ke-2"
- Codelab Modul Migrasi 20 "Menambahkan layanan Pengguna App Engine ke aplikasi Flask"
Migrasi App Engine
- Menggunakan library pihak ketiga di aplikasi Python 2
- Perubahan pada
app.yamldi runtime generasi ke-2 (Python 3) - Panduan migrasi Cloud NDB
- Konten migrasi Cloud NDB
Platform App Engine
- Dokumentasi App Engine
- Runtime Python 2 App Engine (lingkungan standar)
- Menggunakan library bawaan App Engine di App Engine Python 2
- Runtime Python 3 App Engine (lingkungan standar)
- Perbedaan antara runtime Python 2 & 3 App Engine (lingkungan standar)
- Panduan migrasi aplikasi Python 2 ke 3 App Engine (lingkungan standar)
- Informasi harga dan kuota App Engine
- Peluncuran platform App Engine generasi kedua (2018)
- Membandingkan platform generasi pertama & kedua
- Dukungan jangka panjang untuk runtime lama
- Contoh migrasi dokumentasi
- Contoh migrasi hasil kontribusi komunitas
Cloud SDK
- Google Cloud SDK
- Alat command line Cloud SDK
gcloud - Mengaktifkan (& menonaktifkan) Google API
- Pengelola API konsol cloud (mengaktifkan/menonaktifkan API)
- Mengaktifkan Google API dengan
gcloud - Mencantumkan Google API dengan
gcloud
Informasi Cloud lainnya
- Python di Google Cloud
- Dokumentasi library klien Python
- Repositori library klien Python
- Paket"Selalu Gratis"
- Cloud SDK
- Alat command line Cloud SDK
gcloud - Semua dokumentasi Google Cloud
Video
- Serverless Migration Station
- Ekspedisi Tanpa Server
- Berlangganan Google Cloud Tech
- Subscribe ke Google Developers
Lisensi
Karya ini dilisensikan berdasarkan Lisensi Umum Creative Commons Attribution 2.0.