Bermigrasi dari layanan Pengguna App Engine ke Cloud Identity Platform (Modul 21)

1. Ringkasan

Rangkaian codelab Stasiun Migrasi Serverless (tutorial interaktif dan mandiri) dan video terkait bertujuan untuk membantu developer tanpa server Google Cloud memodernisasi aplikasi mereka dengan memandu mereka melalui satu atau beberapa migrasi, terutama yang beralih dari layanan lama. Dengan melakukannya, aplikasi Anda akan menjadi lebih portabel serta memberi Anda lebih banyak opsi dan fleksibilitas, sehingga Anda dapat berintegrasi dengan dan mengakses lebih banyak produk Cloud serta melakukan upgrade 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 platform lainnya jika berlaku.

Tujuan codelab ini adalah menunjukkan kepada developer App Engine Python 2 cara bermigrasi dari API/layanan App Engine Users ke Cloud Identity Platform (GCIP). Terdapat 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 sudah selesai dan memigrasikan penggunaannya ke Cloud Identity Platform.

Anda akan mempelajari cara

  • Mengganti penggunaan layanan Pengguna App Engine dengan Cloud Identity Platform
  • Mengganti penggunaan App Engine NDB dengan Cloud NDB (lihat juga Modul 2)
  • Menyiapkan berbagai penyedia identitas autentikasi 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

Survei

Bagaimana Anda akan menggunakan tutorial ini?

Hanya membacanya Membacanya dan menyelesaikan latihan

Bagaimana penilaian Anda terhadap pengalaman dengan Python?

Pemula Menengah Mahir

Bagaimana penilaian Anda terhadap pengalaman menggunakan layanan Google Cloud?

Pemula Menengah Mahir

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 untuk digunakan dalam aplikasi, serta mendukung konsep pengguna admin dan fungsi khusus admin. Untuk meningkatkan portabilitas aplikasi, Google Cloud merekomendasikan untuk memigrasikan dari layanan paket App Engine lama ke layanan mandiri Cloud, misalnya, dari layanan Pengguna ke Cloud Identity Platform.

Identity Platform didasarkan pada Firebase Authentication, dan menambahkan sejumlah fitur perusahaan termasuk autentikasi multi-faktor, OIDC & Dukungan SSO SAML, multi-tenancy, SLA 99,95%, dan banyak lagi. Perbedaan ini juga disorot pada halaman perbandingan produk Identity Platform dan Firebase Authentication. Kedua produk tersebut memiliki fitur yang jauh lebih banyak daripada fungsi yang diberikan oleh layanan Pengguna.

Codelab Modul 21 ini menunjukkan peralihan autentikasi pengguna aplikasi dari layanan Pengguna ke fitur Identity Platform yang paling mencerminkan fungsi yang ditunjukkan dalam Modul 20. Modul 21 juga menampilkan migrasi dari App Engine NDB ke Cloud NDB untuk akses Datastore, yang mengulang 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. Anda dapat terus menggunakan layanan Users saat mengupgrade ke Python 3 karena bermigrasi ke Identity Platform bersifat opsional. Lihat codelab Modul 17 dan video untuk mempelajari cara terus menggunakan layanan paket saat mengupgrade ke runtime generasi ke-2 seperti Python 3.

Tutorial ini menampilkan langkah-langkah berikut:

  1. Penyiapan/Prakerja
  2. Update konfigurasi
  3. Mengubah kode aplikasi

3. Penyiapan/Prakerja

Bagian ini menjelaskan cara:

  1. Menyiapkan project Cloud
  2. Dapatkan aplikasi contoh dasar pengukuran
  3. Deploy (ulang) dan validasi aplikasi dasar pengukuran
  4. Mengaktifkan layanan/API Google Cloud baru

Langkah-langkah ini memastikan Anda memulai dengan kode yang berfungsi yang siap dimigrasikan ke layanan Cloud mandiri.

1. Siapkan project

Jika Anda telah 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 aktif dan aplikasi App Engine yang aktif. Temukan project ID Anda dan siapkan selama codelab ini, lalu gunakan setiap kali Anda menemukan variabel PROJ_ID.

2. Dapatkan aplikasi contoh dasar pengukuran

Salah satu prasyarat adalah aplikasi App Engine Modul 20 yang berfungsi. Jadi, selesaikan codelab-nya (direkomendasikan; link di atas) atau salin kode Modul 20 dari repo. Baik Anda menggunakan kartu milik Anda atau kami, ini adalah tempat kita akan memulai ("MULAI"). Codelab ini memandu Anda melakukan migrasi, dan mengakhirinya dengan kode yang menyerupai yang ada di folder repo Modul 21 ("FINISH").

Salin folder repo Modul 20. Outputnya akan terlihat seperti di bawah ini, dan mungkin memiliki folder lib jika Anda melakukan codelab Modul 20:

$ ls
README.md               appengine_config.py     templates
app.yaml                main.py                 requirements.txt

3. Deploy (ulang) dan validasi aplikasi dasar pengukuran

Jalankan langkah-langkah berikut untuk men-deploy aplikasi Modul 20:

  1. Hapus folder lib jika ada dan jalankan pip install -t lib -r requirements.txt untuk mengisinya kembali. Anda mungkin perlu menggunakan pip2 jika sudah menginstal Python 2 dan 3.
  2. Pastikan Anda telah menginstal dan melakukan inisialisasi alat command line gcloud dan meninjau penggunaannya.
  3. Jika Anda tidak ingin memasukkan PROJ_ID dengan setiap perintah gcloud yang dikeluarkan, tetapkan project Cloud dengan gcloud config set project PROJ_ID terlebih dahulu.
  4. Men-deploy aplikasi contoh dengan gcloud app deploy
  5. Pastikan 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 beserta kunjungan terbaru (diilustrasikan di bawah).

907e64c19ef964f8.pngS

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

ad7b59916b69a035.png

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

867bcb3334149e4.pngS

4. Mengaktifkan API/layanan Google Cloud baru

Pengantar

Aplikasi Modul 20 menggunakan App Engine NDB dan Users API, yakni layanan paket yang tidak memerlukan penyiapan tambahan, tetapi layanan Cloud mandiri memerlukannya, dan aplikasi yang diupdate akan menerapkan Cloud Identity Platform dan Cloud Datastore (melalui library klien Cloud NDB). Selain itu, kebutuhan kita untuk menentukan bahwa pengguna admin App Engine juga memerlukan penggunaan Cloud Resource Manager API.

Biaya

  • App Engine dan Cloud Datastore memiliki "Selalu Gratis" tingkat, dan selama tidak melebihi batas tersebut, Anda tidak akan dikenai biaya saat menyelesaikan tutorial ini. Lihat juga halaman harga App Engine dan halaman harga Cloud Datastore untuk mengetahui detail selengkapnya.
  • Penggunaan Cloud Identity Platform akan dikenai biaya bergantung pada 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 sendiri tidak memerlukan pengaktifan penagihan selama Anda tidak melebihi kuota harian tanpa instrumentasinya. Jadi, pertimbangkan hal ini untuk project Cloud yang tidak melibatkan layanan/API Cloud yang memerlukan penagihan.
  • Penggunaan Cloud Resource Manager API gratis sebagian besar sesuai dengan 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, dan telusuri API menggunakan kotak penelusuran. c7a740304e9d35b.png

Aktifkan API ini:

Cari dan klik tombol Enable untuk setiap API secara terpisah—Anda mungkin akan diminta untuk memberikan informasi penagihan. Misalnya, berikut adalah halaman untuk Resource Manager API:

fc7bd8f4c49d12e5.png

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

8eca12d6cc7b45b0.pngS

Aktifkan Cloud Datastore dengan cara yang sama:

83811599b110e46b.png

Dari command line

Meskipun mengaktifkan API dari konsol secara visual bersifat informatif, sebagian orang lebih menyukai command line. Anda mendapatkan bonus tambahan karena dapat mengaktifkan sejumlah API sekaligus. Jalankan perintah ini untuk mengaktifkan API Cloud Datastore dan Cloud Resource Manager, lalu tunggu hingga operasi selesai, seperti yang digambarkan 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 untuk memberikan informasi penagihan.

"URL" untuk setiap API yang digunakan dalam perintah di atas disebut nama layanan API, dan dapat ditemukan di bagian bawah halaman library untuk setiap API. Jika ingin mengaktifkan Cloud API lainnya untuk aplikasi Anda sendiri, Anda dapat menemukan nama layanannya masing-masing di halaman API terkait. Perintah ini mencantumkan semua nama layanan untuk API yang dapat Anda aktifkan:

gcloud services list --available --filter="name:googleapis.com"

Setelah Anda menyelesaikan langkah-langkah di atas, contoh kami kini dapat mengakses API tersebut, baik di konsol Cloud maupun di command line. 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 ini:

  1. Buka halaman Cloud Identity Platform di Cloud Marketplace, lalu klik tombol Enable di sana. Upgrade dari Firebase Authentication jika diminta. Tindakan ini akan membuka fitur tambahan, seperti yang dijelaskan sebelumnya di bagian Latar Belakang. Berikut adalah halaman Marketplace yang menyoroti tombol Enable: 28475f1c9b29de69.pngS
  2. Setelah Identity Platform diaktifkan, Anda dapat otomatis diarahkan ke halaman Identity Providers. Jika tidak, gunakan link praktis ini untuk membukanya. fc2d92d42a5d1dd7.png
  3. Aktifkan penyedia Google Auth. Jika tidak ada penyedia yang 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 ringan. Di aplikasi Anda sendiri, Anda dapat mengaktifkan penyedia autentikasi tambahan.
  4. Setelah Anda memilih dan menyiapkan Google serta penyedia autentikasi lain yang diinginkan, klik Detail Penyiapan Aplikasi, lalu dari jendela dialog memastikan, salin apiKey dan authDomain di objek config pada tab Web, sehingga keduanya disimpan di tempat yang aman. Mengapa tidak menyalin semuanya? Cuplikan dalam dialog ini di-hardcode dan diberi tanggal, jadi cukup simpan bagian terpentingnya dan gunakan dalam kode kita dengan penggunaan Firebase Auth yang lebih banyak secara serentak. Setelah menyalin nilai dan menyimpannya di tempat yang aman, klik tombol Close, untuk menyelesaikan semua penyiapan yang diperlukan. bbb09dcdd9be538e.png

4. Update konfigurasi

Update pada konfigurasi mencakup perubahan berbagai file konfigurasi serta pembuatan versi 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 melakukan modernisasi 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 sekarang 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 untuk perintah runtime, dan setel ke versi Python 3 yang saat ini didukung. Saat ini contoh 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 handler file statis. Jika aplikasi Anda memilikinya, biarkan semuanya tetap utuh. Anda dapat menghapus semua pengendali skrip jika diinginkan atau membiarkannya di sana sebagai referensi selama Anda mengubah nama sebutan channel mereka menjadi auto, seperti yang dijelaskan dalam panduan migrasi app.yaml. Dengan perubahan ini, app.yaml yang diupdate untuk Python 3 disederhanakan untuk:

SETELAH:

runtime: python310

Pembaruan konfigurasi lainnya

Baik tetap menggunakan Python 2 atau 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 memperbarui template web, templates/index.html.

Memperbarui impor dan inisialisasi

Ikuti langkah-langkah di bawah ini untuk mengupdate impor dan menginisialisasi resource aplikasi:

  1. Untuk impor, ganti NDB App Engine dengan Cloud NDB.
  2. Bersama dengan Cloud NDB, impor juga Cloud Resource Manager.
  3. Identity Platform didasarkan pada Firebase Auth, jadi impor Firebase Admin SDK.
  4. Cloud API mengharuskan penggunaan klien API. Jadi, mulai untuk Cloud NDB, tepat di bawah inisialisasi Flask.

Meskipun paket Cloud Resource Manager diimpor di sini, kita akan menggunakannya pada tahap berikutnya dalam inisialisasi aplikasi. Berikut adalah impor dan inisialisasi dari Modul 20, yang diikuti dengan tampilan bagian-bagian tersebut 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 untuk ditambahkan ke aplikasi yang mendukung pengenalan pengguna admin:

  • _get_gae_admins() — mengumpulkan kumpulan pengguna admin; dipanggil sekali dan disimpan
  • is_admin() — memeriksa apakah pengguna yang login adalah pengguna admin; diminta saat login pengguna

Fungsi utilitas, _get_gae_admins(), memanggil Resource Manager API untuk mengambil allow-policy Cloud IAM saat ini. Kebijakan izinkan menentukan dan menerapkan peran yang diberikan kepada akun utama tertentu (pengguna manusia, akun layanan, dll.). Penyiapannya meliputi:

  • Mengambil ID project Cloud (PROJ_ID)
  • Membuat klien Resource Manager API (rm_client)
  • Membuat kumpulan peran Admin App Engine (_TARGETS) (hanya baca)

Resource Manager memerlukan project ID Cloud, jadi impor google.auth.default() dan panggil fungsi tersebut untuk mendapatkan project ID. Panggilan tersebut menampilkan parameter yang terlihat seperti URL, tetapi merupakan cakupan izin OAuth2. Saat menjalankan aplikasi di cloud, misalnya, di aplikasi App Engine atau VM Compute Engine, akun layanan default disediakan yang memiliki hak istimewa luas. Dengan mengikuti 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 dapat berfungsi dengan baik. Panggilan Resource Manager API yang akan kita lakukan adalah get_iam_policy() yang memerlukan salah satu cakupan berikut agar dapat beroperasi:

  • 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

Aplikasi contoh hanya memerlukan akses hanya baca ke allow-policy. Alat ini tidak memodifikasi kebijakan juga tidak memerlukan akses ke seluruh project. Itu berarti aplikasi tidak membutuhkan 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 kumpulan pengguna admin kosong (admins), mengambil allow_policy melalui get_iam_policy(), dan melakukan loop melalui semua binding yang secara khusus mencari peran Admin App Engine:

  • roles/viewer
  • roles/editor
  • roles/owner
  • roles/appengine.appAdmin

Untuk setiap peran target yang ditemukan, peran ini mengumpulkan pengguna mana yang memiliki peran tersebut, dan menambahkannya ke kumpulan pengguna admin secara keseluruhan. Berakhir dengan menampilkan semua pengguna admin yang ditemukan dan di-cache sebagai konstanta (_ADMINS) selama masa pakai instance App Engine ini. Kami akan segera melihat panggilan tersebut.

Tambahkan definisi fungsi _get_gae_admins() berikut ke main.py tepat di bawah ini, dengan membuat 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:

  1. Pemeriksaan cepat dilakukan dari template web setelah pengguna login ke Firebase.
  2. Saat status autentikasi berubah dalam template, panggilan fetch() gaya Ajax dibuat ke /is_admin yang pengendalinya adalah fungsi berikutnya, is_admin().
  3. Token ID Firebase diteruskan dalam isi POST ke is_admin(), yang mengambilnya dari header dan memanggil Firebase Admin SDK untuk memvalidasinya. Jika ini adalah pengguna yang valid, ekstrak alamat emailnya dan periksa apakah pengguna tersebut adalah pengguna admin.
  4. Hasil Boolean kemudian dikembalikan 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 tersebut diperlukan untuk mereplikasi fungsi yang tersedia dari layanan Pengguna, khususnya fungsi is_current_user_admin(). Panggilan fungsi di Modul 20 ini melakukan semua tugas berat, tidak seperti Modul 21 di mana kita menerapkan solusi pengganti. Kabar baiknya adalah aplikasi ini 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 "{i>admin user<i}" untuk aplikasi Anda sendiri hanya dengan beralih ke peran yang diinginkan di _TARGETS, sedangkan layanan Pengguna di-hardcode untuk peran admin App Engine.

Melakukan inisialisasi Firebase Auth dan meng-cache pengguna admin App Engine

Kita dapat melakukan inisialisasi Firebase Auth di bagian atas di dekat tempat yang sama dengan tempat aplikasi Flask diinisialisasi dan klien Cloud NDB API dibuat, tetapi hal ini tidak perlu dilakukan sampai semua kode admin telah ditentukan, dan ini adalah tempat kita sekarang. Demikian pula, setelah _get_gae_admins() ditentukan, panggil untuk meng-cache daftar pengguna admin.

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

Lihat 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 dalam store_visit() dan fetch_visits() di dalam blok with Python. Update ini sama dengan Modul 2. Buat 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 utamanya adalah sisi klien. Akibatnya, banyak 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 data pertama yang tercantum akan terkait dengan pengelolaan pengguna dan berbeda-beda bergantung pada apakah pengguna sudah login atau tidak:

  • who — email pengguna jika login atau pengguna jika tidak login
  • admin — Badge (admin) jika pengguna yang login adalah admin
  • sign — tampilkan tombol Login atau Logout
  • link — link login atau logout saat tombol diklik
  • visits — 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 beralih ke template web, jadi kita hanya tinggal melakukan kunjungan, mengembalikan pengendali utama kembali ke apa yang kita lakukan 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)

Perbarui template web

Seperti apa tampilan semua pembaruan dari bagian sebelumnya dalam {i>template<i}? Sebagian besar pemindahan pengelolaan pengguna dari aplikasi ke Firebase Auth yang berjalan di template dan port parsial dari semua kode yang kami pindahkan ke JavaScript. Kami melihat main.py sedikit menyusut, jadi perkirakan pertumbuhan yang serupa dalam 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 dalam isi HTML ini, jadi mari kita ambil satu per satu.

Impor Firebase

Saat masih berada di header dokumen HTML, setelah melewati judul halaman, impor komponen Firebase yang dibutuhkan. Komponen Firebase kini dipecah menjadi beberapa modul demi efisiensi. Kode untuk melakukan inisialisasi Firebase diimpor dari modul aplikasi Firebase utama, sedangkan fungsi yang mengelola Firebase auth, Google sebagai penyedia autentikasi, login dan logout, dan "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 telah menyimpan apiKey dan authDomain dari dialog Application Setup Details. Tambahkan nilai-nilai tersebut ke variabel firebaseConfig di bagian berikutnya. Tautan menuju petunjuk lebih detail tersedia 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 menginisialisasi Firebase dengan informasi konfigurasi ini.

// initialize Firebase app & auth components
initializeApp(firebaseConfig);
var auth = getAuth();
var provider = new GoogleAuthProvider();
//provider.setCustomParameters({prompt: 'select_account'});

Setelan ini menetapkan kemampuan untuk menggunakan Google sebagai penyedia autentikasi, dan menyediakan opsi yang diberi komentar untuk menampilkan pemilih akun meskipun hanya ada satu Akun Google yang terdaftar dalam sesi browser Anda. Dengan kata lain, saat memiliki beberapa akun, Anda akan melihat "pemilih akun" ini seperti yang diharapkan: a38369389b7c4c7e.png Namun, jika hanya ada satu pengguna di sesi, proses login akan selesai secara otomatis tanpa interaksi pengguna. (Pop-up akan muncul lalu menghilang.) Anda dapat memaksa dialog pemilih akun agar muncul untuk satu pengguna (vs. langsung login ke aplikasi) dengan menghapus tanda komentar pada baris parameter kustom. Jika diaktifkan, bahkan login satu pengguna akan menampilkan pemilih akun: b75624cb68d94557.png

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 "pengguna yang sudah login" konteks template vs. "pengguna telah logout" konteks akan dialihkan di sini. Kondisional di bagian atas akan menghasilkan true jika pengguna berhasil login, sehingga memicu tindakan berikut:

  1. Alamat email pengguna disetel untuk ditampilkan.
  2. Tombol Login berubah menjadi Logout.
  3. Panggilan gaya Ajax ke /is_admin dibuat untuk menentukan apakah akan menampilkan badge pengguna admin (admin).

Saat pengguna logout, klausa else dijalankan untuk mereset semua informasi pengguna:

  1. Nama pengguna ditetapkan ke user
  2. Semua badge admin dihapus
  3. Tombol Logout diubah kembali menjadi Login

Variabel template

Setelah bagian header berakhir, bagian utama dimulai dengan variabel template yang diganti dengan elemen HTML yang berubah sesuai kebutuhan:

  1. Nama pengguna yang ditampilkan
  2. Badge admin (admin) (jika ada)
  3. 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> akhir 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>

Bagian ini mengakhiri perubahan yang diperlukan pada template aplikasi dan web untuk beralih dari App Engine NDB dan Users API ke Cloud NDB dan Identity Platform, serta melakukan upgrade ke Python 3. Selamat, Anda telah tiba di aplikasi contoh Modul 21 yang baru! Versi kami tersedia untuk ditinjau di folder repo Modul 21b.

Bagian codelab berikutnya bersifat opsional (*) dan hanya untuk pengguna yang aplikasinya harus tetap berada di Python 2, yang akan memandu Anda melalui langkah-langkah yang diperlukan untuk sampai di aplikasi Python 2 Module 21 yang berfungsi.

6. *Backport Python 2

Bagian opsional ini ditujukan untuk developer yang melakukan migrasi Identity Platform, tetapi harus terus menjalankan migrasi di runtime Python 2. Jika Anda tidak mengkhawatirkan hal ini, lewati bagian ini.

Untuk membuat aplikasi Modul 21 versi Python 2 yang berfungsi, Anda memerlukan hal berikut:

  1. Persyaratan runtime: File konfigurasi yang mendukung Python 2, dan perubahan yang diperlukan di aplikasi utama untuk menghindari inkompatibilitas Python 3
  2. 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 hilang tersebut.

Mari kita lakukan langkah-langkah tersebut sekarang, dimulai dari konfigurasi.

Pulihkan appengine_config.py

Di awal tutorial ini, Anda dipandu untuk menghapus appengine_config.py karena tidak digunakan oleh runtime App Engine Python 3. Untuk Python 2, tidak hanya harus dipertahankan, appengine_config.py Modul 20 harus diperbarui 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 untuk Cloud NDB dan Cloud Resource Manager.

Anda akan menambahkan paket tersebut ke app.yaml untuk sementara, 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 vendor) yang diinstal di folder lib dapat berkomunikasi dengan library bawaan.

Terapkan update berikut ke 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. Diperlukan beberapa baris lagi, jadi update appengine_config.py sehingga 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 lebih lanjut tentang perubahan yang diperlukan untuk mendukung library klien Cloud dapat ditemukan dalam dokumentasi memigrasikan layanan paket.

app.yaml

Serupa 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 (yang tidak secara eksplisit terkait dengan migrasi Identity Platform) yang memerlukan penggunaan library klien Cloud Storage, dan yang memerlukan paket pihak ketiga bawaan lainnya, ssl. Tambahkan ketiganya di bagian libraries baru, dengan memilih "terbaru" versi yang tersedia dari paket tersebut, untuk 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 Python 3 requirements.txt. Situasi untuk Python 2 lebih kompleks:

  • Resource Manager API menyediakan fungsi allow-policy yang diperlukan untuk aplikasi contoh. Sayangnya, dukungan ini belum tersedia di versi Python 2 final dari library klien Cloud Resource Manager. (Ini hanya tersedia di versi Python 3.)
  • Akibatnya, diperlukan cara alternatif untuk mengakses fitur ini dari API. Solusinya adalah menggunakan library klien Google API tingkat lebih rendah untuk berkomunikasi dengan API. Untuk beralih ke library klien ini, ganti google-cloud-resource-manager dengan paket google-api-python-client tingkat yang lebih rendah.
  • Karena Python 2 telah dihentikan, grafik dependensi yang mendukung Modul 21 mengharuskan penguncian paket tertentu ke versi tertentu. Beberapa paket harus dipanggil meskipun tidak ditentukan dalam app.yaml Python 3.

SEBELUM:

flask

Mulai requirements.txt Modul 20, perbarui kode 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 diperbarui di repo saat dependensi berubah, tetapi app.yaml ini cukup untuk aplikasi yang berfungsi pada saat penulisan ini.

Pembaruan konfigurasi lainnya

Jika Anda belum menghapus folder lib di bagian sebelumnya di codelab ini, lakukan sekarang. Dengan requirements.txt yang baru diperbarui, berikan perintah yang sudah dikenal ini untuk menginstal persyaratan ini ke lib:

pip install -t lib -r requirements.txt  # or pip2

Jika sudah menginstal Python 2 dan 3 pada sistem pengembangan, Anda mungkin harus 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 level lebih rendah, bukan library klien Resource Manager untuk mengakses API. Tidak diperlukan pembaruan pada 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 ini:

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 yang lebih rendah. Mari kita bahas apa saja yang berubah terlebih dahulu, lalu beri Anda semua kode untuk diperbarui.

Kode Python 2 mengharuskan penggunaan kredensial dan project ID yang ditampilkan dari google.auth.default(). Kredensial tidak digunakan di Python 3, jadi kredensial ini ditetapkan ke variabel dummy garis bawah umum ( _ ). 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, jadi kita menggunakan nama variabel yang sama (rm_client). Salah satu perbedaannya adalah, 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 lebih rendah menampilkan kamus Python dengan tanda kurung siku ( [ ] ) digunakan, misalnya, gunakan binding.role untuk library klien Resource Manager dibandingkan binding['role'] untuk library tingkat lebih rendah. yang pertama juga menggunakan "underscore_separated" nama versus pustaka tingkat rendah yang lebih memilih "CamelCased" ditambah cara yang sedikit berbeda untuk meneruskan parameter API.

Perbedaan penggunaan tersebut ditunjukkan di bawah ini:

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 Python 3 _get_gae_admins() dengan versi Python 2 yang setara:

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 update karena bergantung pada _get_gae_admins() yang telah diupdate.

Langkah ini menyimpulkan perubahan yang diperlukan untuk melakukan backport aplikasi Python 3 Modul 21 ke Python 2. Selamat, Anda telah tiba di aplikasi contoh Modul 21 yang telah diperbarui! Anda akan menemukan semua kode di folder repo Modul 21a.

7. Ringkasan/Pembersihan

Langkah terakhir dalam codelab ini adalah memastikan akun utama (pengguna atau akun layanan) yang menjalankan aplikasi ini memiliki izin yang tepat untuk melakukannya, lalu men-deploy aplikasi Anda untuk mengonfirmasi bahwa aplikasi tersebut berfungsi sebagaimana mestinya dan perubahan tersebut tercermin dalam output.

Kemampuan untuk membaca kebijakan yang diizinkan IAM

Sebelumnya, kami memperkenalkan empat peran yang diperlukan agar diakui sebagai pengguna admin App Engine, tetapi kini ada peran kelima yang harus Anda ketahui:

  • roles/viewer
  • roles/editor
  • roles/owner
  • roles/appengine.appAdmin
  • roles/resourcemanager.projectIamAdmin (untuk akun utama yang mengakses kebijakan izin IAM)

Peran roles/resourcemanager.projectIamAdmin memungkinkan akun utama menentukan apakah pengguna akhir adalah anggota peran admin App Engine mana pun. Tanpa keanggotaan di roles/resourcemanager.projectIamAdmin, panggilan ke Cloud Resource Manager API untuk mendapatkan allow-policy akan gagal.

Anda tidak perlu melakukan tindakan eksplisit apa pun di sini karena aplikasi Anda akan berjalan dengan akun layanan default App Engine yang secara otomatis diberi 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 baik. 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 menghasilkan kebijakan IAM yang diperbarui untuk project Anda, tempat Anda dapat mengonfirmasi bahwa akun layanan memiliki keanggotaan di roles/resourcemanager.projectIamAdmin. Untuk informasi selengkapnya, lihat dokumentasi referensi. Untuk mengulangi, Anda tidak perlu mengeluarkan perintah tersebut dalam codelab ini, tetapi simpan perintah 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 sama dengan aplikasi Modul 20, kecuali bahwa Anda telah berhasil mengganti layanan Pengguna App Engine dengan Cloud Identity Platform (dan Firebase Auth) untuk pengelolaan pengguna:

3a83ae745121d70.pngS

Satu perbedaan yang akan Anda lihat dibandingkan dengan Modul 20 adalah bahwa mengklik Login akan menghasilkan pop-up, bukan pengalihan, seperti pada beberapa screenshot di bawah ini. Namun, seperti Modul 20, perilaku ini 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 umum akan muncul:

8437f5f3d489a942.pngS

Jika ada satu pengguna terdaftar dengan browser Anda, tetapi login di tempat lain, tidak ada dialog yang muncul (atau aplikasi akan langsung muncul dan ditutup), dan aplikasi akan beralih ke status login (menampilkan email pengguna dan tombol Logout).

Beberapa developer mungkin ingin menyediakan pemilih akun, bahkan untuk satu pengguna:

b75624cb68d94557.png

Untuk menerapkannya, hapus tanda 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. Jika sudah login, pop-up akan hilang, dan aplikasi beralih ke status login.

c454455b6020d5e4.png

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

49ebe4dcc1eff11f.pngS

Hal yang sama berlaku saat pengguna admin telah login:

44302f35b39856eb.pngS

Tidak seperti Modul 21, Modul 20 selalu mengakses logika untuk konten template web dari aplikasi (kode sisi server). Kekurangan dari Modul 20 adalah satu kunjungan didaftarkan saat pengguna akhir membuka aplikasi untuk pertama kali, dan kunjungan lainnya didaftarkan saat pengguna login.

Untuk Modul 21, logika login hanya dilakukan di template web (kode sisi klien). Tidak diperlukan perjalanan sisi server untuk menentukan konten yang akan ditampilkan. Satu-satunya panggilan yang dilakukan ke server adalah pemeriksaan pengguna admin setelah pengguna akhir login. Artinya, login dan logout tidak mencatat kunjungan tambahan, sehingga daftar kunjungan terbaru tetap sama untuk tindakan pengelolaan pengguna. Perhatikan bahwa screenshot di atas menampilkan kumpulan 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 pengurutan kronologis.

Pembersihan

Umum

Jika sudah selesai untuk saat ini, sebaiknya nonaktifkan aplikasi App Engine agar tidak menimbulkan penagihan. Namun, jika Anda ingin menguji atau bereksperimen lagi, platform App Engine memiliki kuota gratis, dan asalkan Anda tidak melebihi tingkat penggunaan tersebut, Anda tidak akan dikenai biaya. Itu berlaku 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 "Khusus untuk codelab ini" di bawah ini.

Untuk pengungkapan penuh, deployment ke platform komputasi serverless Google Cloud seperti App Engine akan menimbulkan biaya build dan penyimpanan yang kecil. Cloud Build memiliki kuota gratisnya sendiri seperti halnya Cloud Storage. Penyimpanan gambar tersebut menghabiskan sebagian kuota tersebut. Namun, Anda mungkin tinggal di region yang tidak memiliki paket gratis tersebut, jadi perhatikan penggunaan penyimpanan Anda untuk meminimalkan potensi biaya. "Folder" Cloud Storage tertentu yang harus Anda tinjau mencakup:

  • 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
  • Link penyimpanan di atas bergantung pada PROJECT_ID dan LOCasi Anda, misalnya, "us" jika aplikasi Anda dihosting di AS.

Di sisi lain, jika Anda tidak akan melanjutkan aplikasi ini atau codelab migrasi terkait lainnya dan ingin menghapus semuanya sepenuhnya, nonaktifkan project Anda.

Khusus untuk codelab ini

Layanan yang tercantum di bawah bersifat 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 Cloud Identity Platform memiliki beberapa tingkat "gratis", tergantung pada layanan mana yang Anda gunakan. Lihat halaman harganya untuk mengetahui detail selengkapnya.
  • Penggunaan Cloud Resource Manager API gratis sebagian besar sesuai dengan halaman harganya.

Langkah berikutnya

Selain tutorial ini, modul migrasi lain yang berfokus untuk beralih dari layanan paket lama yang perlu dipertimbangkan meliputi:

  • Modul 2: bermigrasi dari App Engine ndb ke Cloud NDB
  • Modul 7-9: bermigrasi dari Task Queue App Engine (tugas push) ke Cloud Tasks
  • Modul 12-13: bermigrasi dari Memcache App Engine ke Cloud Memorystore
  • Modul 15-16: bermigrasi dari Blobstore App Engine ke Cloud Storage
  • Modul 18-19: bermigrasi dari Task Queue App Engine (tugas pull) 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, berikut adalah alasan bagus untuk mempertimbangkan beralih ke Cloud Functions. Jika containerization telah menjadi bagian dari alur kerja pengembangan aplikasi Anda, terutama jika terdiri dari pipeline CI/CD (continuous integration/continuous delivery atau deployment), sebaiknya lakukan migrasi ke Cloud Run. Skenario ini dibahas dalam modul berikut:

  • Bermigrasi dari App Engine ke Cloud Functions: lihat Modul 11
  • Bermigrasi dari App Engine ke Cloud Run: lihat Modul 4 untuk menyimpan aplikasi Anda ke dalam container dengan Docker, atau Modul 5 untuk melakukannya tanpa container, pengetahuan Docker, atau Dockerfile

Beralih ke platform serverless lainnya bersifat opsional, dan sebaiknya pertimbangkan opsi terbaik untuk aplikasi dan kasus penggunaan Anda sebelum melakukan perubahan apa pun.

Terlepas dari modul migrasi yang Anda pertimbangkan berikutnya, semua konten Stasiun Migrasi Serverless (codelab, video, kode sumber [jika tersedia]) dapat diakses di repositori open source-nya. README repo juga memberikan panduan tentang migrasi yang perlu dipertimbangkan dan "urutan" yang relevan Modul Migrasi.

8. Referensi lainnya

Di bawah ini adalah referensi tambahan untuk developer yang mempelajari lebih lanjut modul migrasi ini atau terkait. Di bawah ini, Anda dapat memberikan masukan tentang konten ini, menemukan link ke kode, dan berbagai 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

Modul 20

kode

(T/A)

Modul 21 (codelab ini)

kode

kode

Referensi {i>online<i}

Berikut adalah referensi yang relevan untuk tutorial ini:

Cloud Identity Platform dan Cloud Marketplace

Cloud Resource Manager, Cloud IAM, Firebase Admin SDK

Pengguna App Engine, App Engine NDB, Cloud NDB, Cloud Datastore

Referensi Modul Migrasi lainnya

Migrasi App Engine

Platform App Engine

Cloud SDK

Informasi Cloud lainnya

Video

Lisensi

Karya ini dilisensikan berdasarkan Lisensi Umum Creative Commons Attribution 2.0.