1. Genel Bakış
Serverless Migration Station serisi codelab'ler (kendi hızınızda ilerleyebileceğiniz, uygulamalı eğitimler) ve ilgili videolar, Google Cloud sunucusuz geliştiricilerin öncelikle eski hizmetlerden uzaklaşarak bir veya daha fazla taşıma işlemi yapmalarına rehberlik ederek uygulamalarını modernleştirmelerine yardımcı olmayı amaçlar. Bu sayede uygulamalarınız daha taşınabilir hale gelir, daha fazla seçenek ve esneklik elde edersiniz. Böylece daha geniş bir Cloud ürün yelpazesiyle entegrasyon yapabilir, bu ürünlere erişebilir ve yeni dil sürümlerine daha kolay yükseltebilirsiniz. Başlangıçta öncelikle App Engine (standart ortam) geliştiricileri olmak üzere en eski Cloud kullanıcılarına odaklanılsa da bu seri, Cloud Functions ve Cloud Run gibi diğer sunucusuz platformları veya uygun olduğu durumlarda başka platformları da kapsayacak kadar geniştir.
Bu codelab'in amacı, Python 2 App Engine geliştiricilerine App Engine Users API/hizmetinden Cloud Identity Platform'a (GCIP) nasıl geçiş yapacaklarını göstermektir. Ayrıca, Datastore erişimi için App Engine NDB'den Cloud NDB'ye örtülü bir taşıma (öncelikle Taşıma Modülü 2'de ele alınır) ve Python 3'e yükseltme de vardır.
20. modülde, Kullanıcılar API'sinin kullanımını 1. modüldeki örnek uygulamaya ekleme konusu ele alınmaktadır. Bu modülde, tamamlanmış 20. modül uygulamasını alıp kullanımını Cloud Identity Platform'a taşıyacaksınız.
Bu demoda aşağıdaki işlemleri yapmayı öğreneceksiniz:
- App Engine Users hizmetinin kullanımını Cloud Identity Platform ile değiştirme
- App Engine NDB kullanımını Cloud NDB ile değiştirin (2. Modül'e de bakın).
- Firebase Auth kullanarak farklı kimlik doğrulama kimlik sağlayıcıları ayarlama
- Proje IAM bilgilerini almak için Cloud Resource Manager API'yi kullanma
- Kullanıcı bilgilerini almak için Firebase Admin SDK'sını kullanma
- Örnek uygulamayı Python 3'e taşıma
İhtiyacınız olanlar
- Etkin bir GCP faturalandırma hesabına sahip bir Google Cloud Platform projesi
- Temel Python becerileri
- Yaygın Linux komutları hakkında çalışma bilgisi
- App Engine uygulamalarını geliştirme ve dağıtma hakkında temel bilgiler
- Çalışan bir 20. Modül App Engine örnek uygulaması
Anket
Bu eğitimi nasıl kullanacaksınız?
Python ile ilgili deneyiminizi nasıl değerlendirirsiniz?
Google Cloud hizmetlerini kullanma deneyiminizi nasıl değerlendirirsiniz?
2. Arka plan
App Engine Users hizmeti, App Engine uygulamaları tarafından kullanılmak üzere tasarlanmış bir kullanıcı kimlik doğrulama sistemidir. Kimlik sağlayıcı olarak Google ile Oturum Açma'yı sunar, uygulamalarda kullanılmak üzere kolay oturum açma ve kapatma bağlantıları sağlar ve yönetici kullanıcılar ile yalnızca yöneticilere yönelik işlevler kavramını destekler. Uygulama taşınabilirliğini iyileştirmek için Google Cloud, eski App Engine paketlenmiş hizmetlerinden Cloud bağımsız hizmetlerine geçiş yapmanızı önerir. Örneğin, Kullanıcılar hizmetinden Cloud Identity Platform'a geçiş yapabilirsiniz.
Identity Platform, Firebase Authentication'a dayanır ve çok öğeli kimlik doğrulama, OIDC ve SAML TOA desteği, çok kiracılı yapı, %99, 95 HDS gibi bir dizi kurumsal özellik ekler. Bu farklılıklar, Identity Platform ve Firebase Authentication ürün karşılaştırma sayfasında da vurgulanmaktadır. Her iki ürün de Users Service'in sunduğu işlevlerden çok daha fazla özelliğe sahiptir.
Bu 21. modül codelab'inde, uygulamanın kullanıcı kimlik doğrulamasını Users hizmetinden 20. modülde gösterilen işlevselliği en iyi şekilde yansıtan Identity Platform özelliklerine geçirme işlemi gösterilmektedir. 21. modülde, Datastore erişimi için App Engine NDB'den Cloud NDB'ye geçiş de ele alınmaktadır. Bu geçiş, 2. Modül'deki geçişle aynıdır.
20. modül kodu, Python 2 örnek uygulaması olarak "tanıtılsa" da kaynağın kendisi Python 2 ve 3 ile uyumludur ve 21. modülde Identity Platform'a (ve Cloud NDB'ye) geçiş yapıldıktan sonra da bu şekilde kalır. Identity Platform'a geçiş isteğe bağlı olduğundan Python 3'e yükseltirken Kullanıcılar hizmetini kullanmaya devam edebilirsiniz. Python 3 gibi 2. nesil çalışma zamanlarına yükseltirken paketlenmiş hizmetleri kullanmaya nasıl devam edeceğinizi öğrenmek için 17. modülün codelab'ini ve videoyu inceleyin.
Bu eğitimde aşağıdaki adımlar yer almaktadır:
- Kurulum/Ön Hazırlık
- Yapılandırmayı güncelleyin
- Uygulama kodunu değiştirme
3. Kurulum/Ön Hazırlık
Bu bölümde aşağıdakilerin nasıl yapılacağı açıklanmaktadır:
- Cloud projenizi ayarlama
- Temel örnek uygulamayı edinme
- Temel uygulamayı (yeniden) dağıtma ve doğrulama
- Yeni Google Cloud hizmetlerini/API'lerini etkinleştirme
Bu adımlar, bağımsız Cloud hizmetlerine taşınmaya hazır, çalışan bir kodla başlamanızı sağlar.
1. Proje oluşturma
20. Modül'deki codelab'i tamamladıysanız aynı projeyi (ve kodu) yeniden kullanın. Alternatif olarak, yepyeni bir proje oluşturun veya mevcut başka bir projeyi yeniden kullanın. Projenin etkin bir faturalandırma hesabına ve etkin bir App Engine uygulamasına sahip olduğundan emin olun. Proje kimliğinizi bulun ve bu codelab sırasında elinizin altında bulundurun. PROJ_ID değişkeniyle karşılaştığınızda proje kimliğinizi kullanın.
2. Temel örnek uygulamayı edinme
Ön koşullardan biri, çalışan bir 20. Modül App Engine uygulamasıdır. Bu nedenle, codelab'ini tamamlayın (önerilir; yukarıdaki bağlantı) veya depodaki 20. Modül kodunu kopyalayın. İster kendi verilerinizi ister bizim verilerimizi kullanın, işe buradan başlayacağız ("BAŞLANGIÇ"). Bu codelab, 21. modülün depo klasöründeki ("FINISH") koda benzeyen bir kodla sonuçlanan taşıma sürecinde size yol gösterir.
- BAŞLANGIÇ: Module 20 folder (Python 2)
- BİTİRME: 21. modül klasörleri ( Python 2 veya Python 3)
- Deponun tamamı (ZIP dosyasını klonlamak veya indirmek için)
Module 20 repo klasörünü kopyalayın. Aşağıdaki çıkışa benzer görünmelidir ve 20. modül kod laboratuvarını yaptıysanız muhtemelen bir lib klasörü içerir:
$ ls README.md appengine_config.py templates app.yaml main.py requirements.txt
3. Temel uygulamayı (yeniden) dağıtma ve doğrulama
Modül 20 uygulamasını dağıtmak için aşağıdaki adımları uygulayın:
- Varsa
libklasörünü silin vepip install -t lib -r requirements.txtkomutunu çalıştırarak klasörü yeniden doldurun. Hem Python 2 hem de 3 yüklüysepip2kullanmanız gerekebilir. gcloudkomut satırı aracını yüklediğinizden, başlattığınızdan ve kullanımını incelediğinizden emin olun.- Verilen her
gcloudkomutundaPROJ_IDdeğerini girmek istemiyorsanız öncegcloud config set projectPROJ_IDile Cloud projesini ayarlayın. - Örnek uygulamayı
gcloud app deployile dağıtma - Uygulamanın hatasız bir şekilde beklendiği gibi çalıştığını doğrulayın. 20. modülün codelab'ini tamamladıysanız uygulama, en son ziyaretlerle birlikte üst kısımda kullanıcı giriş bilgilerini (kullanıcı e-postası, olası "yönetici rozeti" ve giriş/çıkış düğmesi) gösterir (aşağıda gösterilmiştir).

Normal kullanıcı olarak oturum açıldığında kullanıcının e-posta adresi görüntülenir ve "Giriş" düğmesi "Çıkış" düğmesine dönüşür:

Yönetici kullanıcı olarak oturum açıldığında kullanıcının e-posta adresi, yanında "(yönetici)" ifadesiyle birlikte gösterilir:

4. Yeni Google Cloud API'lerini/hizmetlerini etkinleştirme
Giriş
20. Modül uygulaması, ek kurulum gerektirmeyen paketlenmiş hizmetler olan App Engine NDB ve Users API'lerini kullanır. Ancak bağımsız Cloud hizmetleri ek kurulum gerektirir. Güncellenen uygulama hem Cloud Identity Platform'u hem de Cloud Datastore'u (Cloud NDB istemci kitaplığı aracılığıyla) kullanır. Ayrıca, App Engine yönetici kullanıcılarını belirlememiz için Cloud Resource Manager API'nin kullanılması gerekir.
Maliyet
- App Engine ve Cloud Datastore'da "Daima Ücretsiz" katman kotaları vardır. Bu sınırların altında kaldığınız sürece bu eğitimi tamamlarken herhangi bir ücret ödemezsiniz. Daha fazla bilgi için App Engine fiyatlandırma sayfası ve Cloud Datastore fiyatlandırma sayfasına da göz atın.
- Cloud Identity Platform'un kullanımı, aylık etkin kullanıcı sayısına (MAU) veya kimlik doğrulama işlemlerine göre faturalandırılır. Her kullanım modeli için "ücretsiz" sürüm mevcuttur. Daha fazla bilgi için fiyatlandırma sayfasına göz atın. Ayrıca, App Engine ve Cloud Datastore faturalandırma gerektirirken GCIP'nin tek başına kullanımı, enstrümansız günlük kotalarını aşmadığınız sürece faturalandırmanın etkinleştirilmesini gerektirmez. Bu nedenle, faturalandırma gerektiren Cloud API'lerinin/hizmetlerinin kullanılmadığı Cloud projelerinde bunu göz önünde bulundurun.
- Cloud Resource Manager API'nin kullanımı, fiyatlandırma sayfasında belirtildiği gibi büyük ölçüde ücretsizdir.
Kullanıcılar, tercihlerine bağlı olarak Cloud API'leri Cloud Console'dan veya komut satırından (Cloud SDK'nın bir parçası olan gcloud komutu aracılığıyla) etkinleştirir. Cloud Datastore ve Cloud Resource Manager API'leriyle başlayalım.
Cloud Console'dan
Cloud Console'da API Yöneticisi'nin Kitaplık sayfasına (doğru proje için) gidin ve arama çubuğunu kullanarak bir API arayın. 
Şu API'leri etkinleştirin:
Her API için Etkinleştir düğmesini ayrı ayrı bulun ve tıklayın. Faturalandırma bilgileri istenebilir. Örneğin, Resource Manager API'nin sayfasını aşağıda görebilirsiniz:

Etkinleştirildikten sonra (genellikle birkaç saniye sonra) düğme Yönet olarak değişir:

Cloud Datastore'u da aynı şekilde etkinleştirin:

Komut satırından
API'leri konsoldan etkinleştirmek görsel olarak bilgilendirici olsa da bazı kullanıcılar komut satırını tercih eder. Ayrıca, istediğiniz sayıda API'yi aynı anda etkinleştirebilirsiniz. Hem Cloud Datastore hem de Cloud Resource Manager API'lerini etkinleştirmek için bu komutu verin ve işlemin tamamlanmasını bekleyin.
$ gcloud services enable cloudresourcemanager.googleapis.com datastore.googleapis.com Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Fatura bilgileri istenebilir.
Yukarıdaki komutta kullanılan her API'nin "URL'leri" API hizmet adları olarak adlandırılır ve her API'nin kitaplık sayfasının en altında bulunabilir. Kendi uygulamalarınız için diğer Cloud API'lerini etkinleştirmek istiyorsanız ilgili hizmet adlarını API sayfalarında bulabilirsiniz. Bu komut, etkinleştirebileceğiniz API'lerin tüm hizmet adlarını listeler:
gcloud services list --available --filter="name:googleapis.com".
İster Cloud Console'da ister komut satırında olsun, yukarıdaki adımları tamamladığınızda örneğimiz artık bu API'lere erişebilir. Sonraki adımlar, Cloud Identity Platform'u etkinleştirmek ve gerekli kod değişikliklerini yapmaktır.
Cloud Identity Platform'u etkinleştirme ve ayarlama (yalnızca Cloud Console)
Cloud Identity Platform, Google Cloud dışındaki bir kaynağa (ör. Firebase Authentication) bağlandığı veya bu kaynağa bağlı olduğu için bir Marketplace hizmetidir. Şu anda yalnızca Cloud Console'dan Marketplace hizmetlerini etkinleştirebilirsiniz. Aşağıdaki adımları uygulayın:
- Cloud Marketplace'teki Cloud Identity Platform sayfasına gidin ve Etkinleştir düğmesini tıklayın. İstenirse Firebase Authentication'dan yükseltme yapın. Bu işlem, Arka plan bölümünde daha önce açıklananlar gibi ek özellikleri etkinleştirir. Etkinleştir düğmesinin vurgulandığı Marketplace sayfası:

- Identity Platform etkinleştirildikten sonra otomatik olarak Kimlik Sağlayıcılar sayfasına yönlendirilebilirsiniz. Aksi takdirde, bu kolay bağlantıyı kullanarak ilgili sayfaya gidebilirsiniz.

- Google Auth sağlayıcısını etkinleştirin. Hiç sağlayıcı ayarlanmadıysa Sağlayıcı ekle'yi tıklayın ve Google'ı seçin. Bu ekrana döndüğünüzde Google girişi etkinleştirilmiş olmalıdır. Bu eğiticide, App Engine Users hizmetini basit bir Google ile Oturum Açma hizmeti olarak yansıtmak için kullandığımız tek kimlik doğrulama sağlayıcı Google'dır. Kendi uygulamalarınızda ek kimlik doğrulama sağlayıcılarını etkinleştirebilirsiniz.
- Google'ı ve diğer istediğiniz kimlik doğrulama sağlayıcılarını seçip ayarladıktan sonra Uygulama Kurulumu Ayrıntıları'nı tıklayın ve açılan iletişim kutusunda, Web sekmesindeki
confignesnesinde yer alanapiKeyveauthDomaindeğerlerini kopyalayıp güvenli bir yere kaydedin. Neden tamamını kopyalamıyorsunuz? Bu iletişim kutusundaki snippet, sabit kodlanmış ve eski bir snippet'tir. Bu nedenle, en önemli kısımları kaydedip daha fazla eşzamanlı Firebase Auth kullanımıyla kodumuzda kullanmanız yeterlidir. Değerleri kopyalayıp güvenli bir yere kaydettikten sonra Kapat düğmesini tıklayarak gerekli tüm kurulumu tamamlayın.
4. Yapılandırmayı güncelleyin
Yapılandırmadaki güncellemeler, çeşitli yapılandırma dosyalarını değiştirmeyi ve App Engine'in eşdeğerini Cloud Identity Platform ekosisteminde oluşturmayı içerir.
appengine_config.py
- Python 3'e yükseltiyorsanız
appengine_config.pyöğesini silin. - Identity Platform'a geçmeyi planlıyorsanız ancak Python 2'de kalacaksanız dosyayı silmeyin. Bunun yerine, Python 2 geri bağlantı noktası sırasında daha sonra güncelleyeceğiz.
requirements.txt
20. modülün requirements.txt dosyasında yalnızca Flask listeleniyordu. For Module 21, add the following packages:
requirements.txt içeriği artık şu şekilde görünmelidir:
flask
google-auth
google-cloud-ndb
google-cloud-resource-manager
firebase-admin
app.yaml
- Python 3'e yükseltmek,
app.yamldosyasını basitleştirmek anlamına gelir. Çalışma zamanı yönergesi dışındaki her şeyi kaldırın ve bunu şu anda desteklenen bir Python 3 sürümüne ayarlayın. Örnekte şu anda 3.10 sürümü kullanılmaktadır. - Python 2'yi kullanmaya devam edecekseniz henüz herhangi bir işlem yapmayın.
ÖNCESİ:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
20. Modül örnek uygulamasında statik dosya işleyicileri yok. Uygulamalarınızda varsa bunları olduğu gibi bırakın. İsterseniz tüm komut dosyası işleyicilerinizi kaldırabilir veya app.yaml taşıma kılavuzunda açıklandığı gibi işleyicilerini auto olarak değiştirdiğiniz sürece referans olarak bırakabilirsiniz. Bu değişikliklerle birlikte, Python 3 için güncellenen app.yaml şu şekilde basitleştirildi:
SONRASI:
runtime: python310
Diğer yapılandırma güncellemeleri
Python 2'de kalmayı veya Python 3'e geçmeyi tercih etseniz de lib klasörünüz varsa bu klasörü silin.
5. Uygulama kodunu değiştirme
Bu bölümde, App Engine Users hizmetinin Cloud Identity Platform ile değiştirilmesiyle ilgili olarak ana uygulama dosyasında (main.py) yapılan güncellemeler yer almaktadır. Ana uygulamayı güncelledikten sonra web şablonunu güncelleyin, templates/index.html.
İçe aktarma işlemlerini ve başlatmayı güncelleme
İçe aktarma işlemlerini güncellemek ve uygulama kaynaklarını başlatmak için aşağıdaki adımları uygulayın:
- İçe aktarmalar için App Engine NDB'yi Cloud NDB ile değiştirin.
- Cloud NDB ile birlikte Cloud Resource Manager'ı da içe aktarın.
- Identity Platform, Firebase Auth'a dayalı olduğundan Firebase Admin SDK'sını içe aktarın.
- Cloud API'leri için bir API istemcisinin kullanılması gerekir. Bu nedenle, Flask'i başlatmanın hemen altında Cloud NDB için API istemcisini başlatın.
Cloud Resource Manager paketi burada içe aktarılırken, uygulama başlatma işleminin sonraki aşamalarında kullanacağız. Aşağıda, 20. modüldeki içe aktarma ve başlatma işlemlerinin yanı sıra yukarıdaki değişiklikler uygulandıktan sonra bölümlerin nasıl görüneceği açıklanmaktadır:
ÖNCESİ:
from flask import Flask, render_template, request
from google.appengine.api import users
from google.appengine.ext import ndb
app = Flask(__name__)
SONRASI:
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()
App Engine Admin kullanıcıları için destek
Uygulamaya, yönetici kullanıcıların tanınmasını destekleyen iki bileşen eklenmelidir:
_get_gae_admins()— Yönetici kullanıcıları toplar; bir kez çağrılır ve kaydedilir.is_admin(): Oturum açan kullanıcının yönetici kullanıcı olup olmadığını kontrol eder. Her kullanıcı girişi yapıldığında çağrılır.
_get_gae_admins() hizmet işlevi, mevcut Cloud IAM izin politikası'nı getirmek için Resource Manager API'yi çağırır. İzin politikası, hangi ana hesaplara (insan kullanıcılar, hizmet hesapları vb.) hangi rollerin verileceğini tanımlar ve zorunlu kılar. Kurulum şunları içerir:
- Bulut projesi kimliği getiriliyor (
PROJ_ID) - Resource Manager API istemcisi oluşturma (
rm_client) - App Engine Yönetici rolleri (
_TARGETS) için (salt okunur) bir küme oluşturma
Resource Manager, Cloud projesi kimliğini gerektirir. Bu nedenle, google.auth.default() öğesini içe aktarın ve proje kimliğini almak için bu işlevi çağırın. Bu çağrıda, URL'ye benzeyen ancak OAuth2 izin kapsamı olan bir parametre bulunur. Uygulamalar bulutta (ör. Compute Engine sanal makinesinde veya App Engine uygulamasında) çalıştırıldığında geniş ayrıcalıklara sahip bir varsayılan hizmet hesabı sağlanır. En az ayrıcalık ilkesi doğrultusunda, kendi kullanıcı tarafından yönetilen hizmet hesaplarınızı oluşturmanızı öneririz.
API çağrıları için uygulamalarınızın kapsamını düzgün çalışmak için gereken minimum seviyeye daha da daraltmanız önerilir. Yapacağımız Resource Manager API çağrısı get_iam_policy() olup çalışması için aşağıdaki kapsamların birini gerektirir:
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
Örnek uygulamanın, izin politikasına yalnızca salt okuma erişimi gerekir. Politikayı değiştirmez ve projenin tamamına erişmesi gerekmez. Bu, uygulamanın gereken ilk üç izne ihtiyacı olmadığı anlamına gelir. Yalnızca sonuncusu gereklidir ve örnek uygulamada bu yöntem uygulanmaktadır.
İşlevin ana gövdesi, boş bir yönetici kullanıcıları grubu (admins) oluşturur, get_iam_policy() aracılığıyla allow_policy değerini getirir ve özellikle App Engine yönetici rollerini arayarak tüm bağlamaları arasında döngü oluşturur:
roles/viewerroles/editorroles/ownerroles/appengine.appAdmin
Bulunan her hedef rol için, bu role ait kullanıcıları derleyip genel yönetici kullanıcıları grubuna ekler. Bu işlem, bulunan ve bu App Engine örneğinin ömrü boyunca sabit (_ADMINS) olarak önbelleğe alınan tüm yönetici kullanıcıları döndürerek sona erer. Bu görüşme kısa süre içinde gösterilir.
Aşağıdaki _get_gae_admins() işlev tanımını, Cloud NDB API istemcisini oluşturmanın hemen altına (ds_client) main.py ekleyin:
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
Kullanıcılar uygulamaya giriş yaptığında şunlar gerçekleşir:
- Kullanıcı Firebase'de oturum açtıktan sonra web şablonunda hızlı bir kontrol yapılır.
- Şablonda kimlik doğrulama durumu değiştiğinde, işleyicisi sonraki işlev olan
is_admin()olan/is_admin'ye Ajax tarzı birfetch()çağrısı yapılır. - Firebase kimlik jetonu, POST gövdesinde
is_admin()işlevine iletilir. Bu işlev, jetonu başlıklardan alır ve doğrulamak için Firebase Admin SDK'sını çağırır. Geçerli bir kullanıcıysa e-posta adresini ayıklayın ve yönetici kullanıcı olup olmadığını kontrol edin. - Ardından, Boole sonucu şablona başarılı bir 200 olarak döndürülür.
_get_gae_admins() ifadesinden hemen sonra is_admin() ifadesini main.py ifadesine ekleyin:
@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
Kullanıcılar hizmetinde (özellikle is_current_user_admin() işlevi) sunulan işlevlerin kopyalanması için her iki işlevdeki kodun tamamı gereklidir. 21. modülde bir yedek çözüm uyguladığımızın aksine, 20. modüldeki bu işlev çağrısı tüm ağır işleri yaptı. Uygulama artık yalnızca App Engine hizmetine bağlı olmadığından uygulamalarınızı Cloud Run'a veya diğer hizmetlere taşıyabilirsiniz. Ayrıca, _TARGETS bölümünde istediğiniz rollere geçerek kendi uygulamalarınız için "yönetici kullanıcı" tanımını da değiştirebilirsiniz. Kullanıcılar Hizmeti ise App Engine yönetici rolleri için sabit kodlanmıştır.
Firebase Auth'ı başlatma ve App Engine yönetici kullanıcılarını önbelleğe alma
Firebase Auth'u, Flask uygulamasının başlatıldığı ve Cloud NDB API istemcisinin oluşturulduğu yere yakın bir yerde başlatabilirdik ancak tüm yönetici kodu tanımlanana kadar buna gerek yoktu. Şu anda bu noktadayız. Benzer şekilde, _get_gae_admins() tanımlandığına göre artık yönetici kullanıcıların listesini önbelleğe almak için bu işlevi çağırabilirsiniz.
Bu satırları is_admin() işlev gövdesinin hemen altına ekleyin:
# initialize Firebase and fetch set of App Engine admins
initialize_app()
_ADMINS = _get_gae_admins()
Veri modeli güncellemeleri sayfasını ziyaret edin.
Visit veri modeli değişmez. Datastore erişimi için Cloud NDB API istemci bağlam yöneticisinin (ds_client.context()) açıkça kullanılması gerekir. Kodda bu, Datastore çağrılarını Python with bloklarında hem store_visit() hem de fetch_visits() ile sarmalamanız gerektiği anlamına gelir. Bu güncelleme, 2. Modül ile aynıdır. Değişiklikleri aşağıdaki şekilde yapın:
ÖNCESİ:
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)
SONRASI:
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)
Kullanıcı girişi mantığını web şablonuna taşıma
App Engine Users hizmeti sunucu tarafında çalışırken Firebase Auth ve Cloud Identity Platform ağırlıklı olarak istemci tarafında çalışır. Sonuç olarak, 20. Modül uygulamasındaki kullanıcı yönetimi kodunun büyük bir kısmı 21. Modül web şablonuna taşınır.
main.py içinde web bağlamı, şablona beş temel veri parçası iletir. Listelenen ilk dört veri, kullanıcı yönetimiyle bağlantılıdır ve kullanıcının oturum açıp açmamasına bağlı olarak değişir:
who: Oturum açılmışsa kullanıcının e-posta adresi, aksi takdirde useradmin: Oturum açan kullanıcı yöneticiyse (yönetici) rozetisign: Giriş veya Çıkış düğmesini gösterir.link: Düğme tıklamasıyla oturum açma veya kapatma bağlantılarıvisits: En son ziyaretler
ÖNCESİ:
@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)
Tüm kullanıcı yönetimi web şablonuna taşınıyor. Bu nedenle, ana işleyiciyi 1. Modül uygulamasındaki haline geri getiren yalnızca ziyaretler kalıyor:
SONRASI:
@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)
Web şablonunu güncelleme
Önceki bölümdeki tüm güncellemeler şablonda nasıl görünüyor? Temel olarak kullanıcı yönetimi, uygulamadan şablonda çalışan Firebase Auth'a taşınıyor ve taşıdığımız tüm kodun bir kısmı JavaScript'e aktarılıyor. main.py'nın oldukça küçüldüğünü gördük. Bu nedenle, templates/index.html'da da benzer bir büyüme bekliyoruz.
ÖNCESİ:
<!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>
Web şablonunun tamamını aşağıdaki içerikle değiştirin:
SONRASI:
<!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>
Bu HTML gövdesinde birçok bileşen var. Bunları tek tek inceleyelim.
Firebase içe aktarma işlemleri
HTML belgesinin başlığında, sayfa başlığının ötesine geçtikten sonra gereken Firebase bileşenlerini içe aktarın. Firebase bileşenleri artık verimlilik için birden fazla modüle ayrılıyor. Firebase'i başlatma kodu ana Firebase uygulama modülünden içe aktarılırken Firebase kimlik doğrulamasını, kimlik doğrulama sağlayıcısı olarak Google'ı, oturum açma ve kapatmayı, kimlik doğrulama durumu değişikliği "geri çağırmayı" yöneten işlevler Firebase Auth modülünden içe aktarılır:
<!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 yapılandırması
Bu eğitimin Identity Platform kurulumu bölümünde daha önce Application Setup Details (Uygulama Kurulumu Ayrıntıları) iletişim kutusundan apiKey ve authDomain değerlerini kaydetmiştiniz. Bu değerleri, sonraki bölümdeki firebaseConfig değişkenine ekleyin. Yorumlarda daha ayrıntılı talimatların bağlantısı verilmiştir:
// 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",
};
Firebase başlatma
Bir sonraki bölümde, Firebase bu yapılandırma bilgileriyle başlatılır.
// initialize Firebase app & auth components
initializeApp(firebaseConfig);
var auth = getAuth();
var provider = new GoogleAuthProvider();
//provider.setCustomParameters({prompt: 'select_account'});
Bu, Google'ı kimlik doğrulama sağlayıcısı olarak kullanma özelliğini ayarlar ve tarayıcı oturumunuzda yalnızca bir Google Hesabı kayıtlı olsa bile hesap seçicinin gösterilmesi için yorum satırı olarak devre dışı bırakılmış bir seçenek sunar. Başka bir deyişle, birden fazla hesabınız olduğunda bu "hesap seçici" ile karşılaşmanız beklenir:
Ancak oturumda yalnızca bir kullanıcı varsa giriş işlemi, kullanıcı etkileşimi olmadan otomatik olarak tamamlanır. (Pop-up gösterilip kaybolur.) Özel parametre satırındaki yorum işaretini kaldırarak hesap seçici iletişim kutusunun bir kullanıcı için gösterilmesini (uygulamaya hemen giriş yapmak yerine) zorlayabilirsiniz. Etkinleştirilirse tek kullanıcılı girişlerde bile hesap seçici gösterilir: 
Giriş ve çıkış işlevleri
Sonraki kod satırları, giriş veya çıkış düğmesi tıklamalarıyla ilgili işlevleri oluşturur:
// define login and logout button functions
function login() {
signInWithPopup(auth, provider);
};
function logout() {
signOut(auth);
};
Oturum açma ve kapatma işlemleri
Bu <script> blokundaki son ana bölüm, her kimlik doğrulama değişikliği (oturum açma veya kapatma) için çağrılan işlevdir.
// 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>
20. modüldeki, "kullanıcı oturum açtı" şablon bağlamı mı yoksa "kullanıcı oturumu kapattı" bağlamı mı gönderileceğini belirleyen kod buraya taşınır. En üstteki koşul, kullanıcı başarılı bir şekilde giriş yaptığında true sonucunu verir ve aşağıdaki işlemler tetiklenir:
- Kullanıcının e-posta adresi gösterilecek şekilde ayarlanır.
- Giriş düğmesi Çıkış olarak değişir.
(admin)yönetici kullanıcı rozetinin gösterilip gösterilmeyeceğini belirlemek için/is_adminile Ajax tarzı bir çağrı yapılır.
Kullanıcı oturumu kapattığında, tüm kullanıcı bilgilerini sıfırlamak için else ifadesi yürütülür:
- Kullanıcı adı user olarak ayarlandı
- Yönetici rozetleri kaldırıldı
- Çıkış düğmesi tekrar Giriş olarak değiştirildi
Şablon değişkenleri
Başlık bölümü sona erdikten sonra, ana gövde gerekli şekilde değişen HTML öğeleriyle değiştirilen şablon değişkenleriyle başlar:
- Görünen kullanıcı adı
(admin)yönetici rozeti (varsa)- Giriş veya Çıkış düğmesi
<body>
<p>
Welcome, <span id="who"></span> <span id="admin"><code>(admin)</code></span>
<button id="logbtn"></button>
</p><hr>
En son ziyaretler ve HTML öğesi değişkenleri
En son ziyaret kodu değişmez ve son <script> bloğu, hemen yukarıda listelenen oturum açma ve oturum kapatma için değişen HTML öğelerinin değişkenlerini ayarlar:
<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>
Bu, App Engine NDB ve Users API'lerinden Cloud NDB ve Identity Platform'a geçişin yanı sıra Python 3'e yükseltme için uygulamada ve web şablonunda yapılması gereken değişiklikleri özetlemektedir. Yeni 21. Modül örnek uygulamanıza ulaştığınız için tebrik ederiz. Versiyonumuz, Module 21b repo folder içinde incelenebilir.
Bu codelab'in bir sonraki bölümü isteğe bağlıdır (*) ve yalnızca uygulamalarının Python 2'de kalması gereken kullanıcılar içindir. Bu bölümde, çalışan bir Python 2 Modülü 21 uygulamasına ulaşmak için gerekli adımlar açıklanmaktadır.
6. *Python 2 geri bağlantı noktası
Bu isteğe bağlı bölüm, Identity Platform'a geçiş yapan ancak Python 2 çalışma zamanında çalışmaya devam etmesi gereken geliştiriciler içindir. Bu sizin için önemli değilse bu bölümü atlayın.
21. Modül uygulamasının çalışan bir Python 2 sürümünü oluşturmak için aşağıdakilere ihtiyacınız vardır:
- Çalışma zamanı gereksinimleri: Python 2'yi destekleyen yapılandırma dosyaları ve Python 3 ile uyumsuzlukları önlemek için ana uygulamada yapılması gereken değişiklikler
- Küçük kitaplık değişikliği: Python 2, gerekli bazı özellikler Resource Manager istemci kitaplığına eklenmeden önce desteği sonlandırılmıştı. Bu nedenle, eksik işlevlere erişmek için alternatif bir yöntem kullanmanız gerekir.
Şimdi yapılandırmadan başlayarak bu adımları uygulayalım.
appengine_config.py dosyasını geri yükleme
Bu eğitimin önceki bölümlerinde, Python 3 App Engine çalışma zamanı tarafından kullanılmadığı için appengine_config.py öğesini silmeniz istenmişti. Python 2 için yalnızca korunması gerekmez, aynı zamanda appengine_config.py modülünün yerleşik üçüncü taraf kitaplıkların (yani grpcio ve setuptools) kullanımını destekleyecek şekilde güncellenmesi gerekir. Bu paketler, App Engine uygulamanız Cloud NDB ve Cloud Resource Manager gibi Cloud istemci kitaplıklarını her kullandığında gereklidir.
Bu paketleri kısa süre içinde app.yaml'ya ekleyeceksiniz ancak uygulamanızın bunlara erişebilmesi için setuptools'daki pkg_resources.working_set.add_entry() işlevinin çağrılması gerekir. Bu, lib klasörüne yüklenen kopyalanmış (kendiliğinden paketlenmiş veya satıcıdan alınmış) üçüncü taraf kitaplıkların yerleşik kitaplıklarla iletişim kurmasına olanak tanır.
Bu değişikliklerin geçerli olması için appengine_config.py dosyanızda aşağıdaki güncellemeleri uygulayın:
ÖNCESİ:
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
Bu kod tek başına setuptools ve grpcio kullanımını desteklemek için yeterli değildir. Birkaç satır daha eklemeniz gerekiyor. Bu nedenle, appengine_config.py dosyasını aşağıdaki gibi görünecek şekilde güncelleyin:
SONRASI:
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)
Cloud istemci kitaplıklarını desteklemek için gereken değişikliklerle ilgili daha fazla bilgiyi paketlenmiş hizmetleri taşıma belgelerinde bulabilirsiniz.
app.yaml
appengine_config.py'ya benzer şekilde, app.yaml dosyası Python 2'yi destekleyen bir dosyaya geri döndürülmelidir. Orijinal 20. modül app.yaml ile başlayalım:
ÖNCESİ:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Daha önce belirtilen setuptools ve grpcio'ye ek olarak, Cloud Storage istemci kitaplığının kullanılmasını gerektiren bir bağımlılık (Identity Platform taşıma işlemiyle açıkça ilişkili değildir) vardır ve bu, ssl adlı başka bir yerleşik üçüncü taraf paketini gerektirir. libraries bölümüne üçünü de ekleyin. app.yaml için bu paketlerin mevcut "en yeni" sürümlerini seçin:
SONRASI:
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
21. modülde Python 3 requirements.txt'e Google Auth, Cloud NDB, Cloud Resource Manager ve Firebase Admin SDK'yı ekledik. Python 2'deki durum daha karmaşıktır:
- Resource Manager API, örnek uygulama için gereken allow-policy işlevini sağlar. Maalesef bu destek, Cloud Resource Manager istemci kitaplığının nihai Python 2 sürümünde henüz kullanılamıyordu. (Yalnızca Python 3 sürümünde kullanılabilir.)
- Bu nedenle, bu özelliğe API'den erişmek için alternatif bir yöntem gerekir. Çözüm, API ile iletişim kurmak için daha düşük düzeyli Google API'leri istemci kitaplığını kullanmaktır. Bu istemci kitaplığına geçmek için
google-cloud-resource-manageryerine daha düşük düzeydekigoogle-api-python-clientpaketini kullanın. - Python 2'nin desteği sonlandırıldığından, 21. Modülü destekleyen bağımlılık grafiği, belirli paketlerin belirli sürümlere kilitlenmesini gerektirir. Bazı paketler, Python 3
app.yaml'da belirtilmemiş olsa bile çağrılmalıdır.
ÖNCESİ:
flask
20. modülden requirements.txt başlayarak, 21. modül uygulamasının çalışması için aşağıdaki şekilde güncelleyin:
SONRASI:
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
Bağımlılıklar değiştikçe paket ve sürüm numaraları depoda güncellenir ancak bu app.yaml, bu yazı yazıldığı sırada çalışan bir uygulama için yeterlidir.
Diğer yapılandırma güncellemeleri
Bu codelab'in önceki bölümlerinde lib klasörünü silmediyseniz şimdi silin. Yeni güncellenen requirements.txt ile bu gereksinimleri lib'e yüklemek için şu tanıdık komutu verin:
pip install -t lib -r requirements.txt # or pip2
Geliştirme sisteminizde hem Python 2 hem de 3 yüklüyse pip yerine pip2 kullanmanız gerekebilir.
Uygulama kodunu değiştirme
Neyse ki gerekli değişikliklerin çoğu yapılandırma dosyalarında yapılıyor. Uygulama kodunda yapılması gereken tek değişiklik, API'ye erişmek için Resource Manager istemci kitaplığı yerine daha düşük düzeydeki Google API istemci kitaplığını kullanmak üzere küçük bir güncelleme yapmaktır. templates/index.html web şablonunda güncelleme yapılması gerekmez.
İçe aktarma işlemlerini ve başlatmayı güncelleme
Aşağıda gösterildiği gibi Resource Manager istemci kitaplığını (google.cloud.resourcemanager) Google API'leri istemci kitaplığıyla (googleapiclient.discovery) değiştirin:
ÖNCESİ:
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
SONRASI:
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
App Engine Admin kullanıcıları için destek
Daha düşük düzeydeki istemci kitaplığının kullanılabilmesi için _get_gae_admins()'da birkaç değişiklik yapılması gerekir. Önce nelerin değiştiğini ele alalım, ardından güncelleme için gereken tüm kodu size verelim.
Python 2 kodu, google.auth.default()'dan döndürülen hem kimlik bilgilerinin hem de proje kimliğinin kullanılmasını gerektirir. Kimlik bilgileri Python 3'te kullanılmadığı için genel bir alt çizgi ( _ ) sahte değişkenine atanmıştır. Python 2 sürümü için gerekli olduğundan alt çizgiyi CREDS olarak değiştirin. Ayrıca, Resource Manager API istemcisi oluşturmak yerine API istemcisine benzer bir API hizmet uç noktası oluşturacaksınız. Bu nedenle, aynı değişken adını (rm_client) kullanmaya devam ediyoruz. Bir fark, hizmet uç noktası oluşturmak için kimlik bilgilerinin (CREDS) gerekmesidir.
Bu değişiklikler aşağıdaki kodda gösterilmektedir:
ÖNCESİ:
_, PROJ_ID = default( # Application Default Credentials and project ID
['https://www.googleapis.com/auth/cloudplatformprojects.readonly'])
rm_client = resourcemanager.ProjectsClient()
SONRASI:
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)
Diğer bir fark ise Resource Manager istemci kitaplığının noktalı özellik gösterimi kullanan allow-policy nesneleri döndürmesidir. Daha düşük düzeydeki istemci kitaplığı ise köşeli parantezlerin ( [ ]) kullanıldığı Python sözlüklerini döndürür. Örneğin, Resource Manager istemci kitaplığı için binding.role, daha düşük düzeydeki kitaplık için ise binding['role'] kullanılır. Ayrıca, eski kitaplıkta "underscore_separated" adlar ve API parametrelerini iletmek için biraz farklı bir yöntem kullanılırken, alt düzey kitaplık "CamelCased" adları tercih eder.
Bu kullanım farklılıkları aşağıda gösterilmiştir:
ÖNCESİ:
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)
SONRASI:
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'])
Tüm bu değişiklikleri bir araya getirerek Python 3 _get_gae_admins() işlevini eşdeğer Python 2 sürümüyle değiştirin:
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
is_admin() işlevi, zaten güncellenmiş olan _get_gae_admins()'e dayandığı için herhangi bir güncelleme gerektirmez.
Python 3 Modülü 21 uygulamasını Python 2'ye geri aktarmak için gereken değişiklikler burada sona eriyor. Güncellenen 21. modül örnek uygulamanıza ulaştığınız için tebrik ederiz. Tüm kodu Module 21a repo folder içinde bulabilirsiniz.
7. Özet/Temizleme
Codelab'deki son adımlar, bu uygulamayı çalıştıran sorumluların (kullanıcılar veya hizmet hesapları) gerekli izinlere sahip olmasını sağlamak, ardından uygulamanızı amaçlandığı gibi çalıştığını ve değişikliklerin çıkışa yansıtıldığını doğrulamak için dağıtmaktır.
IAM izin politikasını okuma yetkisi
Daha önce, App Engine yönetici kullanıcısı olarak tanınmak için gereken dört rolü tanıtmıştık. Şimdi ise bilmeniz gereken beşinci bir rol var:
roles/viewerroles/editorroles/ownerroles/appengine.appAdminroles/resourcemanager.projectIamAdmin(IAM izin politikasına erişen asıl kullanıcılar için)
roles/resourcemanager.projectIamAdmin rolü, asıl kullanıcıların bir son kullanıcının App Engine yönetici rollerinden herhangi birinin üyesi olup olmadığını belirlemesini sağlar. roles/resourcemanager.projectIamAdmin üyesi olmadan, izin politikasını almak için Cloud Resource Manager API'ye yapılan çağrılar başarısız olur.
Uygulamanız, bu role otomatik olarak üyelik verilen App Engine'in varsayılan hizmet hesabı altında çalışacağı için burada herhangi bir açık işlem yapmanız gerekmez. Geliştirme aşamasında varsayılan hizmet hesabını kullansanız bile, uygulamanızın düzgün çalışması için gereken minimum izinlere sahip bir kullanıcı tarafından yönetilen hizmet hesabı oluşturup kullanmanızı önemle tavsiye ederiz. Bu tür bir hizmet hesabına üyelik vermek için aşağıdaki komutu çalıştırın:
$ 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, Cloud projesi kimliği, USR_MGD_SVC_ACCT@PROJ_ID.iam.gserviceaccount.com ise uygulamanız için oluşturduğunuz kullanıcı tarafından yönetilen hizmet hesabıdır. Bu komut, projenizin güncellenmiş IAM politikasını verir. Burada, hizmet hesabının roles/resourcemanager.projectIamAdmin üyesi olduğunu doğrulayabilirsiniz. Daha fazla bilgi için referans belgelerine bakın. Tekrar belirtmek gerekirse bu codelab'de bu komutu vermeniz gerekmez ancak kendi uygulamalarınızı modernleştirirken referans olarak kullanmak üzere kaydedebilirsiniz.
Uygulamayı dağıtma ve doğrulama
Uygulamanızı standart gcloud app deploy komutuyla buluta yükleyin. Dağıtım tamamlandıktan sonra, kullanıcı yönetimi için App Engine Users hizmetini Cloud Identity Platform (ve Firebase Auth) ile başarıyla değiştirmiş olmanız dışında, 20. Modül uygulamasının neredeyse aynısı olan bir işlev görmeniz gerekir:

20. Modül'e kıyasla fark edeceğiniz bir değişiklik, Giriş'i tıkladığınızda yönlendirme yerine pop-up açılmasıdır. Bu durum, aşağıdaki ekran görüntülerinden bazılarında gösterilmiştir. Ancak 20. modülde olduğu gibi, tarayıcıya kaç Google Hesabı kaydedildiğine bağlı olarak davranış biraz farklılık gösterir.
Tarayıcıya kayıtlı kullanıcı yoksa veya henüz oturum açmamış tek bir kullanıcı varsa genel bir Google ile oturum açma pop-up'ı gösterilir:

Tarayıcınıza tek bir kullanıcı kaydedilmişse ancak bu kullanıcı başka bir yerde oturum açarsa herhangi bir iletişim kutusu görünmez (veya iletişim kutusu açılıp hemen kapanır) ve uygulama oturum açılmış duruma geçer (kullanıcı e-postası ve Oturumu kapat düğmesi gösterilir).
Bazı geliştiriciler, tek bir kullanıcı için bile hesap seçici sağlamak isteyebilir:

Bunu uygulamak için web şablonundaki provider.setCustomParameters({prompt: 'select_account'}); satırının yorumunu daha önce açıklandığı şekilde kaldırın.
Birden fazla kullanıcı varsa hesap seçici iletişim kutusu açılır (aşağıya bakın). Henüz oturum açmadıysa kullanıcıya oturum açması istenir. Oturumunuz zaten açıksa pop-up kaybolur ve uygulama oturum açılmış duruma geçer.

21. modülün oturum açma durumu, 20. modülün kullanıcı arayüzüyle aynı görünüme sahiptir:

Aynı durum, yönetici kullanıcı oturum açtığında da geçerlidir:

21. Modül'ün aksine, 20. Modül her zaman web şablonu içeriğinin mantığına uygulamadan (sunucu tarafı kodu) erişir. 20. Modül'ün bir kusuru, son kullanıcı uygulamaya ilk kez dokunduğunda bir ziyaretin, kullanıcı oturum açtığında ise başka bir ziyaretin kaydedilmesidir.
21. modülde giriş mantığı yalnızca web şablonunda (istemci tarafı kodu) gerçekleşir. Hangi içeriğin gösterileceğini belirlemek için sunucu tarafında gerekli bir gezi yoktur. Sunucuya yapılan tek çağrı, bir son kullanıcı oturum açtıktan sonra yönetici kullanıcıların kontrol edilmesidir. Bu, giriş ve çıkışların ek ziyaret olarak kaydedilmediği anlamına gelir. Bu nedenle, kullanıcı yönetimi işlemleri için en son ziyaretler listesi sabit kalır. Yukarıdaki ekran görüntülerinde, aynı dört ziyaretin birden fazla kullanıcı girişiyle gösterildiğine dikkat edin.
20. Modül'deki ekran görüntüleri, bu codelab'in başında "çift ziyaret hatası"nı gösterir. Her oturum açma veya kapatma işlemi için ayrı ziyaret günlükleri gösterilir. Kronolojik sıralamayı gösteren her ekran görüntüsünün en son ziyaret zaman damgalarını kontrol edin.
Temizleme
Genel
Şimdilik işiniz bittiyse faturalandırmayı önlemek için App Engine uygulamanızı devre dışı bırakmanızı öneririz. Ancak biraz daha test veya deneme yapmak isterseniz App Engine platformunda ücretsiz kota bulunur. Bu nedenle, kullanım katmanını aşmadığınız sürece sizden ücret alınmaz. Bu, işlem için geçerlidir ancak ilgili App Engine hizmetleri için de ücret alınabilir. Daha fazla bilgi için fiyatlandırma sayfasını inceleyin. Bu taşıma işlemine başka Cloud hizmetleri de dahilse bunlar ayrı olarak faturalandırılır. Her iki durumda da varsa aşağıdaki "Bu codelab'e özel" bölümüne bakın.
Tam açıklama yapmak gerekirse App Engine gibi bir Google Cloud sunucusuz bilgi işlem platformuna dağıtım yapıldığında küçük derleme ve depolama maliyetleri oluşur. Cloud Build ve Cloud Storage'ın kendi ücretsiz kotaları vardır. Bu görüntünün depolanması, kotanın bir kısmını kullanır. Ancak, böyle bir ücretsiz katmanın olmadığı bir bölgede yaşıyor olabilirsiniz. Bu nedenle, olası maliyetleri en aza indirmek için depolama alanı kullanımınıza dikkat edin. İncelemeniz gereken belirli Cloud Storage "klasörleri" şunlardır:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- Yukarıdaki depolama bağlantıları
PROJECT_IDveLOCınıza bağlıdır. Örneğin, uygulamanız ABD'de barındırılıyorsa "us" olur.
Öte yandan, bu uygulamaya veya ilgili diğer taşıma codelab'lerine devam etmeyecekseniz ve her şeyi tamamen silmek istiyorsanız projenizi kapatın.
Bu codelab'e özel
Aşağıda listelenen hizmetler bu codelab'e özeldir. Daha fazla bilgi için her ürünün belgelerine bakın:
- App Engine Datastore hizmeti, ücretsiz katmanı da olan Cloud Datastore (Datastore modunda Cloud Firestore) tarafından sağlanır. Daha fazla bilgi için fiyatlandırma sayfasına bakın.
- Cloud Identity Platform'un kullanımı, hangi hizmetlerini kullandığınıza bağlı olarak belirli bir düzeyde "ücretsiz"dir. Daha fazla bilgi için fiyatlandırma sayfasına göz atın.
- Cloud Resource Manager API'nin kullanımı, fiyatlandırma sayfasında belirtildiği gibi büyük ölçüde ücretsizdir.
Sonraki adımlar
Bu eğitimin yanı sıra eski paketlenmiş hizmetlerden geçişe odaklanan diğer taşıma modüllerini de inceleyebilirsiniz:
- 2. Modül: App Engine
ndb'den Cloud NDB'ye taşıma - 7-9. modüller: App Engine görev sırasından (push görevleri) Cloud Tasks'e geçiş
- 12-13. modüller: App Engine Memcache'ten Cloud Memorystore'a geçiş
- 15-16. Modüller: App Engine Blobstore'dan Cloud Storage'a geçiş
- 18-19. Modüller: App Engine görev sırasından (çekme görevleri) Cloud Pub/Sub'a geçiş
App Engine artık Google Cloud'daki tek sunucusuz platform değil. Küçük bir App Engine uygulamanız veya sınırlı işlevselliğe sahip bir uygulamanız varsa ve bunu bağımsız bir mikro hizmete dönüştürmek istiyorsanız ya da tek bir uygulamayı birden fazla yeniden kullanılabilir bileşene ayırmak istiyorsanız Cloud Functions'a geçmeyi düşünebilirsiniz. Container mimarisine alma, özellikle CI/CD (sürekli entegrasyon/sürekli teslim veya dağıtım) ardışık düzeninden oluşuyorsa uygulama geliştirme iş akışınızın bir parçası haline geldiyse Cloud Run'a geçmeyi düşünebilirsiniz. Bu senaryolar aşağıdaki modüllerde ele alınır:
- App Engine'den Cloud Functions'a geçiş: 11. Modül'e bakın.
- App Engine'den Cloud Run'a taşıma: Uygulamanızı Docker ile container mimarisine almak için 4. Modül'e, container'lar, Docker bilgisi veya
Dockerfileolmadan yapmak için 5. Modül'e bakın.
Başka bir sunucusuz platforma geçmek isteğe bağlıdır. Herhangi bir değişiklik yapmadan önce uygulamalarınız ve kullanım alanlarınız için en iyi seçenekleri göz önünde bulundurmanızı öneririz.
Bir sonraki geçiş modülünüz hangisi olursa olsun, tüm Serverless Migration Station içeriklerine (codelab'ler, videolar, kaynak kodu [varsa]) açık kaynaklı depodan erişebilirsiniz. Depodaki README, hangi taşımaların dikkate alınması gerektiği ve ilgili "sıra" hakkında da rehberlik sağlar.
8. Ek kaynaklar
Bu veya ilgili taşıma modüllerini daha ayrıntılı olarak inceleyen geliştiriciler için ek kaynakları aşağıda bulabilirsiniz. Aşağıda bu içerikle ilgili geri bildirimde bulunabilir, kod bağlantılarını ve faydalı bulabileceğiniz çeşitli dokümanları inceleyebilirsiniz.
Codelab'lerle ilgili sorunlar/geri bildirimler
Bu codelab ile ilgili sorun bulursanız lütfen göndermeden önce sorununuzu arayın. Arama yapma ve yeni sorunlar oluşturma bağlantıları:
Taşıma kaynakları
20. Modül (BAŞLANGIÇ) ve 21. Modül (BİTİŞ) ile ilgili depo klasörlerinin bağlantılarını aşağıdaki tabloda bulabilirsiniz.
Codelab | Python 2 | Python 3 |
(yok) | ||
21. Modül (bu codelab) |
Online referanslar
Bu eğitimle ilgili kaynakları aşağıda bulabilirsiniz:
Cloud Identity Platform ve Cloud Marketplace
- Identity Platform ürün sayfası
- Firebase Authentication
- Identity Platform ve Firebase Auth ürün karşılaştırma sayfası
- Identity Platform fiyatlandırma bilgileri
- Identity Platform kotaları (ve enstrümansız kullanım)
- Identity Platform sağlayıcı kurulumu
- Cloud Marketplace ürün sayfası
- Pazar Yeri'ndeki Identity Platform sayfası
Cloud Resource Manager, Cloud IAM, Firebase Admin SDK
- Resource Manager ürün sayfası
- Resource Manager fiyatlandırma bilgileri
- Resource Manager istemci kitaplığı
- Cloud IAM'ye genel bakış (roller, izin politikası vb.)
- Firebase Admin SDK (Python)
App Engine kullanıcıları, App Engine NDB, Cloud NDB, Cloud Datastore
- App Engine kullanıcılarına genel bakış
- App Engine NDB belgeleri
- App Engine NDB deposu
- Cloud NDB istemci kitaplığı
- Cloud NDB deposu
- Cloud Datastore ürün sayfası
- Cloud Datastore fiyatlandırma bilgileri
Diğer taşıma modülü referansları
- Taşıma Modülü'ne giriş
- Tüm "Serverless Migration Station" kaynakları
- Python 3'e taşıma dokümanları
- Taşıma Modülü 17: "2. nesil çalışma zamanlarında paketlenmiş hizmetleri kullanma" codelab'i
- Taşıma Modülü 20 "Flask uygulamalarına App Engine Users Service hizmetini ekleme" codelab'i
App Engine'e taşıma
- Python 2 uygulamalarında üçüncü taraf kitaplıklarını kullanma
- 2. nesil çalışma zamanlarında
app.yamlile ilgili değişiklikler (Python 3) - Cloud NDB'ye taşıma rehberi
- Cloud NDB'ye taşıma ile ilgili içerikler
App Engine platformu
- App Engine belgeleri
- Python 2 App Engine (standart ortam) çalışma zamanı
- Python 2 App Engine'de App Engine'in yerleşik kitaplıklarını kullanma
- Python 3 App Engine (standart ortam) çalışma zamanı
- Python 2 ve 3 App Engine (standart ortam) çalışma zamanları arasındaki farklar
- Python 2'den 3'e App Engine (standart ortam) taşıma kılavuzu
- App Engine fiyatlandırma ve kota bilgileri
- İkinci nesil App Engine platformunun kullanıma sunulması (2018)
- Birinci ve ikinci nesil platformları karşılaştırma
- Eski çalışma zamanları için uzun süreli destek
- Doküman taşıma örnekleri
- Topluluk tarafından gönderilen geçiş örnekleri
Google Cloud SDK
- Google Cloud SDK
- Cloud SDK
gcloudkomut satırı aracı - Google API'lerini etkinleştirme (ve devre dışı bırakma)
- Cloud Console API Yöneticisi (API'leri etkinleştirme/devre dışı bırakma)
gcloudile Google API'lerini etkinleştirme- Google API'lerini
gcloudile listeleme
Diğer Cloud bilgileri
- Google Cloud'da Python
- Python istemci kitaplıkları belgeleri
- Python istemci kitaplıkları depoları
- "Her Zaman Ücretsiz" katmanı
- Google Cloud SDK
- Cloud SDK
gcloudkomut satırı aracı - Tüm Google Cloud belgeleri
Videolar
- Sunucusuz Taşıma İstasyonu
- Sunucusuz Expeditions
- Google Cloud Tech kanalına abone olun.
- Google Developers'a abone olun.
Lisans
Bu çalışma, Creative Commons Attribution 2.0 Genel Amaçlı Lisans ile lisans altına alınmıştır.