App Engine उपयोगकर्ता सेवा से Cloud Identity Platform (मॉड्यूल 21) पर माइग्रेट करना

1. खास जानकारी

सर्वरलेस माइग्रेशन स्टेशन की कोडलैब सीरीज़ (अपने हिसाब से सीखने और प्रैक्टिकल करने वाले ट्यूटोरियल) और इससे जुड़े वीडियो का मकसद, Google Cloud सर्वरलेस डेवलपर की मदद करना है. इससे वे एक या उससे ज़्यादा माइग्रेशन करके, अपने ऐप्लिकेशन को बेहतर बना सकते हैं. इनमें मुख्य रूप से लेगसी सेवाओं से माइग्रेट करना शामिल है. ऐसा करने से, आपके ऐप्लिकेशन को एक जगह से दूसरी जगह ले जाना आसान हो जाता है. साथ ही, आपको ज़्यादा विकल्प और सुविधा मिलती है. इससे आपको Cloud प्रॉडक्ट की ज़्यादा रेंज के साथ इंटिग्रेट करने और उन्हें ऐक्सेस करने में मदद मिलती है. साथ ही, भाषा के नए वर्शन पर आसानी से अपग्रेड किया जा सकता है. शुरुआत में, इस सीरीज़ में मुख्य तौर पर App Engine (स्टैंडर्ड एनवायरमेंट) डेवलपर के लिए कॉन्टेंट शामिल किया गया था. हालांकि, अब इसमें अन्य सर्वरलेस प्लैटफ़ॉर्म के लिए भी कॉन्टेंट शामिल किया गया है. जैसे, Cloud Functions और Cloud Run. इसके अलावा, इसमें अन्य प्लैटफ़ॉर्म के लिए भी कॉन्टेंट शामिल किया गया है.

इस कोडलैब का मकसद, Python 2 App Engine डेवलपर को यह दिखाना है कि App Engine Users API/service से Cloud Identity Platform (GCIP) पर कैसे माइग्रेट किया जाए. Datastore को ऐक्सेस करने के लिए, App Engine NDB से Cloud NDB पर इंप्लिसिट माइग्रेशन भी होता है. यह मुख्य रूप से माइग्रेशन मॉड्यूल 2 में शामिल है. साथ ही, Python 3 में अपग्रेड भी होता है.

मॉड्यूल 20 में, मॉड्यूल 1 के सैंपल ऐप्लिकेशन में Users API का इस्तेमाल करने का तरीका बताया गया है. इस मॉड्यूल में, आपको मॉड्यूल 20 के तैयार ऐप्लिकेशन को Cloud Identity Platform पर माइग्रेट करना होगा.

आपको इनके बारे में जानकारी मिलेगी

  • App Engine Users service की जगह Cloud Identity Platform का इस्तेमाल करना
  • App Engine NDB की जगह Cloud NDB का इस्तेमाल करें. इसके बारे में जानने के लिए, दूसरा मॉड्यूल भी देखें
  • Firebase Auth का इस्तेमाल करके, पुष्टि करने के लिए अलग-अलग आइडेंटिटी प्रोवाइडर सेट अप करना
  • प्रोजेक्ट के IAM की जानकारी पाने के लिए, Cloud Resource Manager API का इस्तेमाल करना
  • उपयोगकर्ता की जानकारी पाने के लिए, Firebase Admin SDK का इस्तेमाल करना
  • सैंपल ऐप्लिकेशन को Python 3 में पोर्ट करना

आपको किन चीज़ों की ज़रूरत होगी

सर्वे

इस ट्यूटोरियल का इस्तेमाल कैसे किया जाएगा?

सिर्फ़ इसे पढ़ें इसे पढ़ें और एक्सरसाइज़ पूरी करें

Python के साथ अपने अनुभव को आप क्या रेटिंग देंगे?

शुरुआती सामान्य एडवांस

Google Cloud की सेवाओं को इस्तेमाल करने के अपने अनुभव को आप क्या रेटिंग देंगे?

शुरुआती सामान्य एडवांस

2. बैकग्राउंड

App Engine Users सेवा, उपयोगकर्ता की पुष्टि करने वाला एक सिस्टम है. इसका इस्तेमाल App Engine ऐप्लिकेशन करते हैं. यह Google Sign-In को आइडेंटिटी प्रोवाइडर के तौर पर इस्तेमाल करता है. साथ ही, ऐप्लिकेशन में इस्तेमाल करने के लिए, लॉगिन और लॉग आउट करने के आसान लिंक उपलब्ध कराता है. इसके अलावा, यह एडमिन उपयोगकर्ताओं और एडमिन के लिए उपलब्ध सुविधाओं के कॉन्सेप्ट के साथ काम करता है. Google Cloud, ऐप्लिकेशन पोर्टेबिलिटी को बेहतर बनाने के लिए, App Engine की लेगसी बंडल की गई सेवाओं से Cloud की स्टैंडअलोन सेवाओं पर माइग्रेट करने का सुझाव देता है. उदाहरण के लिए, Users सेवा से Cloud Identity Platform पर माइग्रेट करना.

Identity Platform, Firebase Authentication पर आधारित है. इसमें कई एंटरप्राइज़ सुविधाएं जोड़ी गई हैं. जैसे, कई चरणों में पुष्टि करने की सुविधा, OIDC और SAML SSO के साथ काम करने की सुविधा, मल्टी-टेनेंसी, 99.95% एसएलए वगैरह. इन दोनों के बीच के फ़र्क़, Identity Platform और Firebase Authentication के प्रॉडक्ट की तुलना करने वाले पेज पर भी हाइलाइट किए गए हैं. दोनों प्रॉडक्ट में, Users सेवा की तुलना में ज़्यादा सुविधाएं हैं.

इस 21वें मॉड्यूल के कोडलैब में, ऐप्लिकेशन के उपयोगकर्ता की पुष्टि करने की सुविधा को Users सेवा से Identity Platform की उन सुविधाओं पर स्विच करने का तरीका बताया गया है जो 20वें मॉड्यूल में दिखाई गई सुविधाओं से मिलती-जुलती हैं. मॉड्यूल 21 में, Datastore को ऐक्सेस करने के लिए App Engine NDB से Cloud NDB पर माइग्रेट करने की सुविधा भी दी गई है. इसमें मॉड्यूल 2 के माइग्रेशन को दोहराया गया है.

मॉड्यूल 20 के कोड को Python 2 के सैंपल ऐप्लिकेशन के तौर पर "प्रमोट" किया गया है. हालांकि, सोर्स Python 2 और 3 के साथ काम करता है. Identity Platform (और Cloud NDB) पर माइग्रेट करने के बाद भी, यह मॉड्यूल 21 में इसी तरह काम करता है. Python 3 पर अपग्रेड करते समय, Users सेवा का इस्तेमाल जारी रखा जा सकता है. ऐसा इसलिए, क्योंकि Identity Platform पर माइग्रेट करना ज़रूरी नहीं है. Python 3 जैसे दूसरी जनरेशन के रनटाइम पर अपग्रेड करते समय, बंडल की गई सेवाओं का इस्तेमाल जारी रखने का तरीका जानने के लिए, मॉड्यूल 17 का कोडलैब और वीडियो देखें.

इस ट्यूटोरियल में ये चरण शामिल हैं:

  1. सेटअप/प्रीवर्क
  2. कॉन्फ़िगरेशन अपडेट करना
  3. ऐप्लिकेशन कोड में बदलाव करना

3. सेटअप/प्रीवर्क

इस सेक्शन में, यह बताया गया है कि:

  1. अपना Cloud प्रोजेक्ट सेट अप करना
  2. बेसलाइन सैंपल ऐप्लिकेशन पाना
  3. बेसलाइन ऐप्लिकेशन को (फिर से) डिप्लॉय करें और उसकी पुष्टि करें
  4. Google Cloud की नई सेवाओं/एपीआई को चालू करना

इन चरणों से यह पक्का किया जाता है कि आपके पास काम करने वाला कोड हो, जिसे स्टैंडअलोन Cloud सेवाओं पर माइग्रेट किया जा सके.

1. प्रोजेक्ट सेट अप करना

अगर आपने मॉड्यूल 20 का कोडलैब पूरा कर लिया है, तो उसी प्रोजेक्ट और कोड का फिर से इस्तेमाल करें. इसके अलावा, एक नया प्रोजेक्ट बनाएं या किसी मौजूदा प्रोजेक्ट का फिर से इस्तेमाल करें. पक्का करें कि प्रोजेक्ट में चालू बिलिंग खाता हो और App Engine ऐप्लिकेशन चालू हो. अपना प्रोजेक्ट आईडी ढूंढें और इस कोडलैब के दौरान इसे अपने पास रखें. साथ ही, जब भी आपको PROJ_ID वैरिएबल दिखे, तब इसका इस्तेमाल करें.

2. बेसलाइन सैंपल ऐप्लिकेशन पाना

इसके लिए, Module 20 App Engine ऐप्लिकेशन का काम करना ज़रूरी है. इसलिए, या तो इसका कोडलैब पूरा करें (सुझाया गया; ऊपर लिंक दिया गया है) या repo से Module 20 कोड कॉपी करें. चाहे आपने अपना प्रॉम्प्ट इस्तेमाल किया हो या हमारा, हम यहीं से शुरू करेंगे ("START"). इस कोडलैब में, माइग्रेट करने का तरीका बताया गया है. इसमें आखिर में ऐसा कोड दिया गया है जो Module 21 के repo फ़ोल्डर ("FINISH") में मौजूद कोड जैसा है.

Module 20 repo फ़ोल्डर को कॉपी करें. यह नीचे दिए गए आउटपुट की तरह दिखना चाहिए. अगर आपने मॉड्यूल 20 का कोडलैब किया है, तो इसमें lib फ़ोल्डर भी हो सकता है:

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

3. बेसलाइन ऐप्लिकेशन को (फिर से) डिप्लॉय करें और उसकी पुष्टि करें

Module 20 ऐप्लिकेशन को डिप्लॉय करने के लिए, यह तरीका अपनाएं:

  1. अगर lib फ़ोल्डर मौजूद है, तो उसे मिटाएं. इसके बाद, pip install -t lib -r requirements.txt चलाकर उसे फिर से भरें. अगर आपने Python 2 और 3, दोनों इंस्टॉल किए हैं, तो आपको pip2 का इस्तेमाल करना पड़ सकता है.
  2. पक्का करें कि आपने gcloud कमांड-लाइन टूल को इंस्टॉल और शुरू कर लिया हो. साथ ही, इसके इस्तेमाल की समीक्षा कर ली हो.
  3. अगर आपको हर gcloud कमांड के साथ अपना PROJ_ID नहीं डालना है, तो पहले gcloud config set project PROJ_ID का इस्तेमाल करके Cloud प्रोजेक्ट सेट करें.
  4. gcloud app deploy की मदद से, सैंपल ऐप्लिकेशन को डिप्लॉय करना
  5. पुष्टि करें कि ऐप्लिकेशन बिना किसी गड़बड़ी के, उम्मीद के मुताबिक काम कर रहा है. अगर आपने मॉड्यूल 20 का कोडलैब पूरा कर लिया है, तो ऐप्लिकेशन में सबसे ऊपर उपयोगकर्ता के लॉगिन की जानकारी दिखती है. जैसे, उपयोगकर्ता का ईमेल, "एडमिन बैज" (अगर उपलब्ध हो), और लॉगिन/लॉग आउट बटन. इसके साथ ही, सबसे हाल ही की विज़िट की जानकारी भी दिखती है. इसकी जानकारी यहां दी गई है.

907e64c19ef964f8.png

सामान्य उपयोगकर्ता के तौर पर साइन-इन करने पर, उपयोगकर्ता का ईमेल पता दिखता है. साथ ही, "लॉगिन करें" बटन, "लॉग आउट करें" बटन में बदल जाता है:

ad7b59916b69a035.png

एडमिन के तौर पर साइन इन करने पर, उपयोगकर्ता का ईमेल पता दिखता है. इसके बगल में "(एडमिन)" लिखा होता है:

867bcb3334149e4.png

4. Google Cloud के नए एपीआई/सेवाएं चालू करना

शुरुआती जानकारी

Module 20 ऐप्लिकेशन, App Engine NDB और Users API का इस्तेमाल करता है. ये बंडल की गई सेवाएं हैं, जिनके लिए अतिरिक्त सेटअप की ज़रूरत नहीं होती. हालांकि, स्टैंडअलोन Cloud सेवाओं के लिए ऐसा करना ज़रूरी होता है. अपडेट किया गया ऐप्लिकेशन, Cloud Identity Platform और Cloud Datastore, दोनों का इस्तेमाल करेगा. Cloud Datastore का इस्तेमाल, Cloud NDB क्लाइंट लाइब्रेरी के ज़रिए किया जाएगा. इसके अलावा, हमें App Engine के एडमिन उपयोगकर्ताओं का पता लगाने के लिए भी Cloud Resource Manager API का इस्तेमाल करना पड़ता है.

लागत

  • App Engine और Cloud Datastore के लिए, "हमेशा मुफ़्त" टियर के कोटे उपलब्ध हैं. जब तक आप इन सीमाओं के अंदर रहते हैं, तब तक इस ट्यूटोरियल को पूरा करने के लिए आपसे कोई शुल्क नहीं लिया जाएगा. ज़्यादा जानकारी के लिए, App Engine का शुल्क और Cloud Datastore का शुल्क पेज भी देखें.
  • Cloud Identity Platform का इस्तेमाल करने पर, हर महीने के सक्रिय उपयोगकर्ताओं (एमएयू) की संख्या या पुष्टि करने की प्रोसेस के हिसाब से बिल भेजा जाता है. इस्तेमाल के हर मॉडल के लिए, "मुफ़्त" वर्शन उपलब्ध है. ज़्यादा जानकारी के लिए, कीमत की जानकारी देने वाला पेज देखें. इसके अलावा, App Engine और Cloud Datastore के लिए बिलिंग की ज़रूरत होती है. हालांकि, GCIP का इस्तेमाल करने के लिए बिलिंग की सुविधा चालू करना ज़रूरी नहीं है. ऐसा तब तक होता है, जब तक इसके लिए तय की गई बिना इंस्ट्रूमेंट वाली रोज़ की सीमा पार न हो जाए. इसलिए, उन Cloud प्रोजेक्ट के लिए इस बात का ध्यान रखें जिनमें बिलिंग की सुविधा ज़रूरी नहीं है.
  • Cloud Resource Manager API का इस्तेमाल ज़्यादातर मुफ़्त में किया जा सकता है. इस बारे में ज़्यादा जानकारी कीमत वाले पेज पर दी गई है.

उपयोगकर्ता, अपनी पसंद के हिसाब से Cloud Console या कमांड-लाइन से Cloud API चालू करते हैं. कमांड-लाइन से Cloud API चालू करने के लिए, Cloud SDK का हिस्सा gcloud कमांड का इस्तेमाल किया जाता है. आइए, Cloud Datastore और Cloud Resource Manager API से शुरुआत करते हैं.

Cloud Console से

Cloud Console में, सही प्रोजेक्ट के लिए एपीआई मैनेजर के लाइब्रेरी पेज पर जाएं. इसके बाद, खोज बार का इस्तेमाल करके कोई एपीआई खोजें. c7a740304e9d35b.png

इन एपीआई को चालू करें:

हर एपीआई के लिए, चालू करें बटन ढूंढें और उस पर क्लिक करें. आपसे बिलिंग की जानकारी मांगी जा सकती है. उदाहरण के लिए, यहां Resource Manager API का पेज दिया गया है:

fc7bd8f4c49d12e5.png

चालू होने के बाद, बटन का नाम बदलकर 'मैनेज करें' हो जाता है. आम तौर पर, ऐसा कुछ सेकंड बाद होता है:

8eca12d6cc7b45b0.png

इसी तरह, Cloud Datastore को चालू करें:

83811599b110e46b.png

कमांड-लाइन से

कंसोल से एपीआई चालू करने पर, विज़ुअल जानकारी मिलती है. हालांकि, कुछ लोग कमांड-लाइन का इस्तेमाल करना पसंद करते हैं. इसके अलावा, एक साथ कई एपीआई चालू करने का विकल्प भी मिलता है. Cloud Datastore और Cloud Resource Manager, दोनों एपीआई को चालू करने के लिए, यह कमांड जारी करें. साथ ही, कार्रवाई पूरी होने का इंतज़ार करें. यहां इसका उदाहरण दिया गया है:

$ gcloud services enable cloudresourcemanager.googleapis.com datastore.googleapis.com
Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.

आपसे बिलिंग की जानकारी मांगी जा सकती है.

ऊपर दिए गए कमांड में इस्तेमाल किए गए हर एपीआई के "यूआरएल" को एपीआई सेवा के नाम कहा जाता है. ये हर एपीआई के लाइब्रेरी पेज पर सबसे नीचे मौजूद होते हैं. अगर आपको अपने ऐप्लिकेशन के लिए अन्य Cloud API चालू करने हैं, तो उनके एपीआई पेजों पर जाकर, उनसे जुड़ी सेवाओं के नाम देखे जा सकते हैं. इस कमांड से, उन सभी एपीआई के नाम दिखते हैं जिन्हें चालू किया जा सकता है:

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

Cloud Console या कमांड-लाइन में, ऊपर दिए गए चरणों को पूरा करने के बाद, हमारा सैंपल अब उन एपीआई को ऐक्सेस कर सकता है. अगले चरण में, Cloud Identity Platform को चालू करना और कोड में ज़रूरी बदलाव करना शामिल है.

Cloud Identity Platform को चालू और सेट अप करना (सिर्फ़ Cloud Console में)

Cloud Identity Platform एक Marketplace सेवा है, क्योंकि यह Google Cloud के बाहर मौजूद किसी संसाधन से कनेक्ट होती है या उस पर निर्भर होती है. उदाहरण के लिए, Firebase Authentication. फ़िलहाल, Cloud Console से ही Marketplace की सेवाएं चालू की जा सकती हैं. नीचे दिए गए चरणों का पालन करें:

  1. Cloud Marketplace में Cloud Identity Platform पेज पर जाएं और वहां मौजूद चालू करें बटन पर क्लिक करें. अगर आपसे Firebase Authentication से अपग्रेड करने के लिए कहा जाता है, तो अपग्रेड करें. इससे आपको अतिरिक्त सुविधाएं मिलेंगी. जैसे, बैकग्राउंड सेक्शन में बताई गई सुविधाएं. यहां Marketplace का पेज दिया गया है, जिसमें चालू करें बटन को हाइलाइट किया गया है: 28475f1c9b29de69.png
  2. Identity Platform चालू होने के बाद, आपको पहचान देने वाली कंपनियां पेज पर अपने-आप ले जाया जा सकता है. अगर ऐसा नहीं है, तो इस लिंक का इस्तेमाल करके वहां जाएं. fc2d92d42a5d1dd7.png
  3. Google Auth उपलब्ध कराने वाली सेवा चालू करें. अगर कोई सेवा देने वाली कंपनी सेट अप नहीं की गई है, तो सेवा देने वाली कंपनी जोड़ें पर क्लिक करें और Google चुनें. इस स्क्रीन पर वापस आने पर, Google एंट्री चालू होनी चाहिए. इस ट्यूटोरियल में, हम सिर्फ़ Google को ऑथराइज़ेशन देने वाली कंपनी के तौर पर इस्तेमाल कर रहे हैं. ऐसा इसलिए, ताकि App Engine Users सेवा को Google Sign-In की हल्की सेवा के तौर पर दिखाया जा सके. अपने ऐप्लिकेशन में, पुष्टि करने की सुविधा देने वाली अन्य कंपनियों को चालू किया जा सकता है.
  4. Google और अन्य पुष्टि करने वाली कंपनियों को चुनने और सेट अप करने के बाद, ऐप्लिकेशन सेटअप की जानकारी पर क्लिक करें. इसके बाद, दिखने वाली डायलॉग विंडो में, वेब टैब पर मौजूद config ऑब्जेक्ट में मौजूद apiKey और authDomain को कॉपी करें. साथ ही, इन दोनों को किसी सुरक्षित जगह पर सेव करें. इसे पूरा कॉपी क्यों नहीं किया जा सकता? इस डायलॉग में मौजूद स्निपेट को हार्डकोड किया गया है और इसकी तारीख भी दी गई है. इसलिए, सिर्फ़ सबसे ज़रूरी बिट सेव करें और उन्हें हमारे कोड में इस्तेमाल करें. साथ ही, Firebase Auth का इस्तेमाल एक साथ कई बार करें. वैल्यू कॉपी करने और उन्हें किसी सुरक्षित जगह पर सेव करने के बाद, बंद करें बटन पर क्लिक करें. इससे ज़रूरी सेटअप पूरा हो जाएगा. bbb09dcdd9be538e.png

4. कॉन्फ़िगरेशन अपडेट करना

कॉन्फ़िगरेशन में अपडेट करने का मतलब है, अलग-अलग कॉन्फ़िगरेशन फ़ाइलों को बदलना. साथ ही, App Engine के बराबर की सुविधा को Cloud Identity Platform के इकोसिस्टम में बनाना.

appengine_config.py

  • Python 3 पर अपग्रेड करने पर, appengine_config.py को मिटाएं
  • अगर आपको Identity Platform पर अपग्रेड करना है, लेकिन Python 2 का इस्तेमाल जारी रखना है, तो फ़ाइल न मिटाएं. इसके बजाय, हम इसे बाद में Python 2 बैकपोर्ट के दौरान अपडेट करेंगे.

requirements.txt

मॉड्यूल 20 की requirements.txt फ़ाइल में सिर्फ़ Flask को शामिल किया गया है. मॉड्यूल 21 के लिए, ये पैकेज जोड़ें:

requirements.txt का कॉन्टेंट अब ऐसा दिखना चाहिए:

flask
google-auth
google-cloud-ndb
google-cloud-resource-manager
firebase-admin

app.yaml

  • Python 3 पर अपग्रेड करने का मतलब है कि app.yaml फ़ाइल को आसान बनाया जा रहा है. रनटाइम डायरेक्टिव को छोड़कर, बाकी सभी डायरेक्टिव हटा दें. साथ ही, उसे Python 3 के ऐसे वर्शन पर सेट करें जो फ़िलहाल काम करता हो. फ़िलहाल, उदाहरण में वर्शन 3.10 का इस्तेमाल किया जा रहा है.
  • अगर आपको Python 2 का इस्तेमाल जारी रखना है, तो अभी कोई कार्रवाई न करें.

BEFORE:

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

Module 20 के सैंपल ऐप्लिकेशन में स्टैटिक फ़ाइल हैंडलर नहीं हैं. अगर आपके ऐप्लिकेशन ऐसा करते हैं, तो उन्हें न हटाएं. अगर चाहें, तो सभी स्क्रिप्ट हैंडलर हटाए जा सकते हैं. इसके अलावा, उन्हें सिर्फ़ रेफ़रंस के लिए रखा जा सकता है. हालांकि, इसके लिए आपको उनके हैंडल को auto में बदलना होगा. इसके बारे में app.yaml माइग्रेशन गाइड में बताया गया है. इन बदलावों के बाद, Python 3 के लिए अपडेट किया गया app.yaml इस तरह से आसान बनाया गया है:

AFTER:

runtime: python310

कॉन्फ़िगरेशन से जुड़े अन्य अपडेट

अगर आपको Python 2 का इस्तेमाल जारी रखना है या Python 3 पर पोर्ट करना है, तो lib फ़ोल्डर को मिटा दें.

5. ऐप्लिकेशन कोड में बदलाव करना

इस सेक्शन में, मुख्य ऐप्लिकेशन फ़ाइल main.py से जुड़े अपडेट दिए गए हैं. इसमें App Engine Users सेवा की जगह Cloud Identity Platform का इस्तेमाल किया गया है. मुख्य ऐप्लिकेशन को अपडेट करने के बाद, आपको वेब टेंप्लेट templates/index.html को अपडेट करना होगा.

इंपोर्ट और इनिशियलाइज़ेशन को अपडेट करना

इंपोर्ट अपडेट करने और ऐप्लिकेशन के संसाधनों को शुरू करने के लिए, यहां दिया गया तरीका अपनाएं:

  1. इंपोर्ट के लिए, App Engine NDB को Cloud NDB से बदलें.
  2. Cloud NDB के साथ-साथ, Cloud Resource Manager को भी इंपोर्ट करें.
  3. Identity Platform, Firebase Auth पर आधारित है. इसलिए, Firebase Admin SDK इंपोर्ट करें.
  4. Cloud API के लिए, एपीआई क्लाइंट का इस्तेमाल करना ज़रूरी है. इसलिए, Flask को शुरू करने से ठीक पहले, Cloud NDB के लिए इसे शुरू करें.

Cloud Resource Manager पैकेज को यहां इंपोर्ट किया गया है. हालांकि, हम इसका इस्तेमाल ऐप्लिकेशन को शुरू करने के बाद करेंगे. यहां मॉड्यूल 20 से इंपोर्ट और इनिशियलाइज़ेशन के बारे में बताया गया है. इसके बाद, ऊपर दिए गए बदलावों को लागू करने के बाद सेक्शन कैसे दिखने चाहिए, इसके बारे में बताया गया है:

BEFORE:

from flask import Flask, render_template, request
from google.appengine.api import users
from google.appengine.ext import ndb

app = Flask(__name__)

AFTER:

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 के एडमिन उपयोगकर्ताओं के लिए सहायता

ऐप्लिकेशन में दो कॉम्पोनेंट जोड़ने होते हैं, ताकि एडमिन उपयोगकर्ताओं की पहचान की जा सके:

  • _get_gae_admins() — यह कुकी, एडमिन उपयोगकर्ताओं का सेट इकट्ठा करती है. इसे एक बार कॉल किया जाता है और सेव किया जाता है
  • is_admin() — यह कुकी यह जांच करती है कि साइन इन किया हुआ उपयोगकर्ता एडमिन है या नहीं. इसे किसी भी उपयोगकर्ता के लॉगिन पर कॉल किया जाता है

यूटिलिटी फ़ंक्शन, _get_gae_admins(), Resource Manager API को कॉल करके, मौजूदा Cloud IAM allow-policy को फ़ेच करता है. अनुमति देने की नीति यह तय करती है कि किन मुख्य खातों (मानव उपयोगकर्ता, सेवा खाते वगैरह) को कौनसी भूमिकाएं दी जाएंगी. साथ ही, यह नीति इन भूमिकाओं को लागू करती है. सेटअप में ये शामिल हैं:

  • Cloud प्रोजेक्ट आईडी (PROJ_ID) फ़ेच किया जा रहा है
  • Resource Manager API क्लाइंट बनाना (rm_client)
  • App Engine एडमिन की भूमिकाओं का (रीड-ओनली) सेट बनाना (_TARGETS)

Resource Manager को Cloud प्रोजेक्ट आईडी की ज़रूरत होती है. इसलिए, google.auth.default() को इंपोर्ट करें और प्रोजेक्ट आईडी पाने के लिए उस फ़ंक्शन को कॉल करें. इस कॉल में एक ऐसा पैरामीटर शामिल है जो दिखने में यूआरएल जैसा लगता है, लेकिन यह OAuth2 की अनुमति का दायरा है. क्लाउड में ऐप्लिकेशन चलाने के लिए, उदाहरण के लिए, Compute Engine VM या App Engine ऐप्लिकेशन पर, डिफ़ॉल्ट सेवा खाता उपलब्ध कराया जाता है. इसके पास कई तरह के विशेषाधिकार होते हैं. हमारा सुझाव है कि आप अपने उपयोगकर्ता के मैनेज किए गए सेवा खाते बनाएं. इससे, कम से कम ज़रूरी अनुमतियां देने के सबसे सही तरीके का पालन किया जा सकेगा.

एपीआई कॉल के लिए, यह सबसे अच्छा है कि आप अपने ऐप्लिकेशन के स्कोप को और कम करें, ताकि वे ठीक से काम कर सकें. हम Resource Manager API कॉल get_iam_policy() करेंगे. इसे काम करने के लिए, इनमें से किसी एक स्कोप की ज़रूरत होती है:

  • 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

सैंपल ऐप्लिकेशन को सिर्फ़ allow-policy को पढ़ने का ऐक्सेस चाहिए. इससे नीति में कोई बदलाव नहीं होता है. साथ ही, इसके लिए पूरे प्रोजेक्ट का ऐक्सेस भी ज़रूरी नहीं है. इसका मतलब है कि ऐप्लिकेशन को पहले तीन अनुमतियों में से किसी की भी ज़रूरत नहीं है. आखिरी वाला तरीका ही ज़रूरी है. हम सैंपल ऐप्लिकेशन के लिए इसी तरीके को लागू कर रहे हैं.

फ़ंक्शन का मुख्य हिस्सा, एडमिन उपयोगकर्ताओं का एक खाली सेट (admins) बनाता है. यह get_iam_policy() के ज़रिए allow_policy को फ़ेच करता है और इसके सभी बाइंडिंग में लूप करता है. यह खास तौर पर App Engine एडमिन की भूमिकाओं को ढूंढता है:

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

यह हर टारगेट भूमिका के लिए, यह जानकारी इकट्ठा करता है कि उस भूमिका में कौनसे उपयोगकर्ता शामिल हैं. साथ ही, उन्हें एडमिन उपयोगकर्ताओं के कुल सेट में जोड़ता है. यह फ़ंक्शन, एडमिन के तौर पर इस्तेमाल किए जाने वाले सभी उपयोगकर्ताओं को वापस भेजता है. साथ ही, उन्हें इस App Engine इंस्टेंस के पूरे जीवनकाल के लिए, एक कॉन्स्टेंट (_ADMINS) के तौर पर कैश मेमोरी में सेव करता है. हम जल्द ही उस कॉल को देखेंगे.

Cloud NDB API क्लाइंट (ds_client) को इंस्टैंशिएट करने के ठीक नीचे, main.py में _get_gae_admins() फ़ंक्शन की परिभाषा जोड़ें:

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

जब उपयोगकर्ता ऐप्लिकेशन में लॉग इन करते हैं, तो यह होता है:

  1. जब कोई उपयोगकर्ता Firebase में साइन इन करता है, तो वेब टेंप्लेट से तुरंत जांच की जाती है.
  2. टेंप्लेट में पुष्टि करने की स्थिति बदलने पर, /is_admin को Ajax-स्टाइल fetch() कॉल किया जाता है. इसका हैंडलर, अगला फ़ंक्शन is_admin() होता है.
  3. Firebase आईडी टोकन को POST बॉडी में is_admin() को पास किया जाता है. यह इसे हेडर से लेता है और इसकी पुष्टि करने के लिए, Firebase Admin SDK को कॉल करता है. अगर यह मान्य उपयोगकर्ता है, तो उसका ईमेल पता निकालें और देखें कि वह एडमिन है या नहीं.
  4. इसके बाद, बूलियन नतीजे को टेंप्लेट में 200 के तौर पर दिखाया जाता है.

_get_gae_admins() के ठीक बाद, main.py में is_admin() जोड़ें:

@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

उपयोगकर्ता सेवा से उपलब्ध सुविधाओं को दोहराने के लिए, दोनों फ़ंक्शन के सभी कोड की ज़रूरत होती है. खास तौर पर, इसके is_current_user_admin() फ़ंक्शन की. मॉड्यूल 20 में इस फ़ंक्शन कॉल ने सभी मुश्किल काम किए. हालांकि, मॉड्यूल 21 में हमने एक विकल्प लागू किया है. अच्छी बात यह है कि अब यह ऐप्लिकेशन, सिर्फ़ App Engine की सेवा पर निर्भर नहीं है. इसका मतलब है कि अपने ऐप्लिकेशन को Cloud Run या अन्य सेवाओं पर ट्रांसफ़र किया जा सकता है. इसके अलावा, अपने ऐप्लिकेशन के लिए "एडमिन उपयोगकर्ता" की परिभाषा को भी बदला जा सकता है. इसके लिए, आपको _TARGETS में जाकर अपनी पसंद की भूमिकाओं पर स्विच करना होगा. हालांकि, App Engine एडमिन की भूमिकाओं के लिए, उपयोगकर्ता सेवा को हार्डकोड किया गया है.

Firebase Auth को शुरू करें और App Engine के एडमिन उपयोगकर्ताओं को कैश मेमोरी में सेव करें

हम Firebase Auth को सबसे ऊपर, उसी जगह पर शुरू कर सकते थे जहां Flask ऐप्लिकेशन शुरू किया गया था और Cloud NDB API क्लाइंट बनाया गया था. हालांकि, जब तक एडमिन कोड तय नहीं हो जाता, तब तक इसकी ज़रूरत नहीं थी. हम अब इसी जगह पर हैं. इसी तरह, अब _get_gae_admins() को तय कर दिया गया है. इसलिए, एडमिन उपयोगकर्ताओं की सूची को कैश मेमोरी में सेव करने के लिए इसे कॉल करें.

इन लाइनों को is_admin() के फ़ंक्शन बॉडी के ठीक नीचे जोड़ें:

# initialize Firebase and fetch set of App Engine admins
initialize_app()
_ADMINS = _get_gae_admins()

डेटा मॉडल के अपडेट के बारे में जानकारी देने वाले पेज पर जाएं

Visit डेटा मॉडल में कोई बदलाव नहीं होता. Datastore को ऐक्सेस करने के लिए, Cloud NDB API क्लाइंट कॉन्टेक्स्ट मैनेजर, ds_client.context() का इस्तेमाल करना ज़रूरी है. कोड में इसका मतलब है कि आपको Python with ब्लॉक में, Datastore कॉल को store_visit() और fetch_visits(), दोनों में रैप करना होगा. यह अपडेट, मॉड्यूल 2 के जैसा ही है. बदलाव करने के लिए, यह तरीका अपनाएं:

BEFORE:

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)

AFTER:

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)

उपयोगकर्ता के लॉगिन लॉजिक को वेब टेंप्लेट में ले जाना

App Engine Users सेवा, सर्वर-साइड होती है. वहीं, Firebase Auth और Cloud Identity Platform मुख्य रूप से क्लाइंट-साइड होते हैं. इस वजह से, Module 20 ऐप्लिकेशन में मौजूद उपयोगकर्ता मैनेजमेंट का ज़्यादातर कोड, Module 21 वेब टेंप्लेट में चला जाता है.

main.py में, वेब कॉन्टेक्स्ट, टेंप्लेट को पांच ज़रूरी डेटा पास करता है. यहां दी गई पहली चार वैल्यू, उपयोगकर्ता के मैनेजमेंट से जुड़ी हैं. साथ ही, ये इस बात पर निर्भर करती हैं कि उपयोगकर्ता ने साइन-इन किया है या नहीं:

  • who — अगर उपयोगकर्ता ने साइन इन किया है, तो उसका ईमेल पता या अगर उसने साइन इन नहीं किया है, तो उपयोगकर्ता
  • admin — अगर साइन इन किया हुआ उपयोगकर्ता एडमिन है, तो (एडमिन) बैज
  • signलॉगिन करें या लॉग आउट करें बटन दिखाएं
  • link — बटन पर क्लिक करने पर, साइन-इन या साइन-आउट करने के लिंक
  • visits — सबसे हाल की विज़िट

BEFORE:

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

उपयोगकर्ता को मैनेज करने की सुविधा को वेब टेंप्लेट में ट्रांसफ़र किया जा रहा है. इसलिए, अब हमारे पास सिर्फ़ विज़िट की जानकारी है. इससे मुख्य हैंडलर को वापस उसी जगह पर ले जाया जा सकेगा जहां वह Module 1 ऐप्लिकेशन में था:

AFTER:

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

वेब टेंप्लेट अपडेट करें

पिछले सेक्शन के सभी अपडेट, टेंप्लेट में कैसे दिखते हैं? हमने उपयोगकर्ता मैनेजमेंट को मुख्य रूप से ऐप्लिकेशन से हटाकर, टेंप्लेट में चल रहे Firebase Auth में ट्रांसफ़र कर दिया है. साथ ही, हमने उस कोड के कुछ हिस्से को JavaScript में पोर्ट कर दिया है. हमने देखा कि main.py में काफ़ी गिरावट आई है. इसलिए, हमें उम्मीद है कि templates/index.html में भी इसी तरह की बढ़ोतरी होगी.

BEFORE:

<!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>

पूरे वेब टेंप्लेट को यहां दिए गए कॉन्टेंट से बदलें:

AFTER:

<!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>

इस एचटीएमएल बॉडी में कई कॉम्पोनेंट हैं. इसलिए, आइए इन्हें एक-एक करके समझते हैं.

Firebase इंपोर्ट

एचटीएमएल दस्तावेज़ के हेडर में रहते हुए, पेज के टाइटल के बाद, ज़रूरी Firebase कॉम्पोनेंट इंपोर्ट करें. Firebase कॉम्पोनेंट को अब कई मॉड्यूल में बांटा गया है, ताकि वे ज़्यादा असरदार तरीके से काम कर सकें. Firebase को शुरू करने का कोड, मुख्य Firebase ऐप्लिकेशन मॉड्यूल से इंपोर्ट किया जाता है. वहीं, Firebase Auth, Google को पुष्टि करने की सुविधा देने वाली कंपनी के तौर पर मैनेज करने वाले फ़ंक्शन, साइन इन और साइन आउट करने वाले फ़ंक्शन, और पुष्टि करने की स्थिति में बदलाव करने वाले "कॉल बैक" फ़ंक्शन, 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";

Firebase कॉन्फ़िगरेशन

इस ट्यूटोरियल के Identity Platform सेटअप के दौरान, आपने ऐप्लिकेशन सेटअप की जानकारी डायलॉग से apiKey और authDomain सेव किए थे. अगले सेक्शन में, उन वैल्यू को firebaseConfig वैरिएबल में जोड़ें. टिप्पणियों में, ज़्यादा जानकारी वाले निर्देशों का लिंक दिया गया है:

// 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 को शुरू करना

अगले सेक्शन में, इस कॉन्फ़िगरेशन की जानकारी के साथ Firebase को शुरू किया जाता है.

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

इससे Google को पुष्टि करने वाले सेवा देने वाली कंपनी के तौर पर इस्तेमाल करने की सुविधा सेट होती है. साथ ही, यह एक ऐसा विकल्प उपलब्ध कराता है जिसमें टिप्पणी की गई है. इससे खाता चुनने वाला टूल तब भी दिखता है, जब आपके ब्राउज़र सेशन में सिर्फ़ एक Google खाता रजिस्टर किया गया हो. दूसरे शब्दों में कहें, तो जब आपके पास एक से ज़्यादा खाते होते हैं, तो आपको यह "खाता चुनने वाला टूल" दिखता है: a38369389b7c4c7e.png हालांकि, अगर सेशन में सिर्फ़ एक उपयोगकर्ता है, तो लॉगिन की प्रोसेस अपने-आप पूरी हो जाती है. इसमें उपयोगकर्ता को कुछ भी करने की ज़रूरत नहीं होती. (इसके बाद, पॉप-अप दिखता है और फिर गायब हो जाता है.) कस्टम पैरामीटर लाइन से टिप्पणी हटाने पर, किसी एक उपयोगकर्ता के लिए खाता चुनने वाला डायलॉग बॉक्स दिखाया जा सकता है. इससे उपयोगकर्ता को ऐप्लिकेशन में तुरंत लॉग इन करने के बजाय, खाता चुनने का विकल्प मिलता है. यह सुविधा चालू होने पर, एक उपयोगकर्ता के लॉगिन करने पर भी खाता चुनने की सुविधा दिखती है: b75624cb68d94557.png

लॉगिन और लॉग आउट करने के फ़ंक्शन

कोड की अगली लाइनें, लॉगिन या लॉग आउट बटन पर क्लिक करने के फ़ंक्शन बनाती हैं:

// define login and logout button functions
function login() {
    signInWithPopup(auth, provider);
};

function logout() {
    signOut(auth);
};

साइन-इन और साइन-आउट करने की कार्रवाइयां

इस <script> ब्लॉक का आखिरी मुख्य सेक्शन, वह फ़ंक्शन है जिसे हर बार पुष्टि में बदलाव होने पर (साइन-इन या साइन-आउट) कॉल किया जाता है.

// 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 में मौजूद कोड, यह तय करता है कि "उपयोगकर्ता ने लॉग इन किया है" टेंप्लेट का कॉन्टेक्स्ट भेजना है या "उपयोगकर्ता ने लॉग आउट किया है" कॉन्टेक्स्ट. इसे यहां ट्रांसफ़र किया जाता है. अगर उपयोगकर्ता ने सफलतापूर्वक लॉग इन किया है, तो सबसे ऊपर मौजूद शर्त के हिसाब से true नतीजे मिलते हैं. इससे ये कार्रवाइयां ट्रिगर होती हैं:

  1. उपयोगकर्ता का ईमेल पता, डिसप्ले के लिए सेट किया गया हो.
  2. लॉगिन करें बटन, लॉग आउट करें में बदल जाता है.
  3. /is_admin को Ajax-स्टाइल कॉल किया जाता है. इससे यह तय किया जाता है कि (admin) एडमिन उपयोगकर्ता बैज दिखाना है या नहीं.

जब उपयोगकर्ता लॉग आउट करता है, तो else क्लॉज़ को लागू किया जाता है, ताकि उपयोगकर्ता की सभी जानकारी रीसेट की जा सके:

  1. उपयोगकर्ता नाम को user पर सेट किया गया है
  2. किसी एडमिन बैज को हटाया गया हो
  3. लॉग आउट करें बटन को वापस लॉग इन करें पर सेट किया गया

टेंप्लेट वैरिएबल

हेडर सेक्शन खत्म होने के बाद, मुख्य बॉडी शुरू होती है. इसमें टेंप्लेट वैरिएबल होते हैं. इन्हें एचटीएमएल एलिमेंट से बदल दिया जाता है. ये एलिमेंट, ज़रूरत के हिसाब से बदलते रहते हैं:

  1. उपयोगकर्ता का डिसप्ले नेम
  2. (admin) एडमिन बैज (अगर लागू हो)
  3. लॉगिन करें या लॉग आउट करें बटन
<body>
<p>
Welcome, <span id="who"></span> <span id="admin"><code>(admin)</code></span>
<button id="logbtn"></button>
</p><hr>

हाल ही की विज़िट और एचटीएमएल एलिमेंट वैरिएबल

सबसे हाल की विज़िट का कोड नहीं बदलता है. साथ ही, फ़ाइनल <script> ब्लॉक, उन एचटीएमएल एलिमेंट के लिए वैरिएबल सेट करता है जो साइन-इन और साइन-आउट के लिए बदलते हैं. ये एलिमेंट, ऊपर दिए गए हैं:

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

App Engine NDB और Users API से Cloud NDB और Identity Platform पर स्विच करने के लिए, ऐप्लिकेशन और वेब टेंप्लेट में ये बदलाव करने ज़रूरी हैं. साथ ही, Python 3 पर अपग्रेड करने के लिए भी ये बदलाव ज़रूरी हैं. बधाई हो, आपने मॉड्यूल 21 का नया सैंपल ऐप्लिकेशन बना लिया है! हमारा वर्शन, Module 21b repo फ़ोल्डर में समीक्षा के लिए उपलब्ध है.

कोड लैब का अगला हिस्सा वैकल्पिक (*) है. यह सिर्फ़ उन लोगों के लिए है जिनके ऐप्लिकेशन को Python 2 पर ही काम करना है. इसमें, Python 2 Module 21 ऐप्लिकेशन को काम करने की स्थिति में लाने के लिए ज़रूरी चरणों के बारे में बताया गया है.

6. *Python 2 बैकपोर्ट

यह सेक्शन उन डेवलपर के लिए है जो Identity Platform को माइग्रेट कर रहे हैं, लेकिन उन्हें Python 2 रनटाइम पर काम करना जारी रखना है. हालांकि, यह सेक्शन इस्तेमाल करना ज़रूरी नहीं है. अगर आपको इससे कोई फ़र्क़ नहीं पड़ता है, तो इस सेक्शन को छोड़ दें.

Module 21 ऐप्लिकेशन का Python 2 वर्शन बनाने के लिए, आपके पास ये चीज़ें होनी चाहिए:

  1. रनटाइम से जुड़ी ज़रूरी शर्तें: Python 2 के साथ काम करने वाली कॉन्फ़िगरेशन फ़ाइलें और मुख्य ऐप्लिकेशन में ज़रूरी बदलाव, ताकि Python 3 के साथ काम न करने से जुड़ी समस्याओं से बचा जा सके
  2. लाइब्रेरी में मामूली बदलाव: Python 2 को बंद कर दिया गया था. इससे पहले, Resource Manager क्लाइंट लाइब्रेरी में ज़रूरी सुविधाएं जोड़ी गई थीं. इसलिए, आपको उस सुविधा को ऐक्सेस करने के लिए किसी दूसरे तरीके का इस्तेमाल करना होगा.

चलिए, अब इन चरणों को पूरा करते हैं. सबसे पहले, कॉन्फ़िगरेशन करते हैं.

appengine_config.py को वापस लाएं

इस ट्यूटोरियल में पहले, आपको appengine_config.py को मिटाने के लिए कहा गया था, क्योंकि इसका इस्तेमाल Python 3 App Engine रनटाइम नहीं करता है. Python 2 के लिए, इसे न सिर्फ़ सुरक्षित रखना ज़रूरी है, बल्कि Module 20 appengine_config.py को भी अपडेट करना ज़रूरी है, ताकि तीसरे पक्ष की बिल्ट-इन लाइब्रेरी का इस्तेमाल किया जा सके. जैसे, grpcio और setuptools. जब भी आपका App Engine ऐप्लिकेशन, Cloud NDB और Cloud Resource Manager जैसी Cloud क्लाइंट लाइब्रेरी का इस्तेमाल करता है, तब इन पैकेज की ज़रूरत होती है.

इन पैकेज को app.yaml में कुछ समय के लिए जोड़ा जाएगा. हालांकि, आपके ऐप्लिकेशन को इन्हें ऐक्सेस करने के लिए, setuptools से pkg_resources.working_set.add_entry() फ़ंक्शन को कॉल करना होगा. इससे, lib फ़ोल्डर में इंस्टॉल की गई तीसरे पक्ष की कॉपी की गई (सेल्फ़-बंडल्ड या वेंडर की) लाइब्रेरी, पहले से मौजूद लाइब्रेरी के साथ कम्यूनिकेट कर पाती हैं.

इन बदलावों को लागू करने के लिए, अपनी appengine_config.py फ़ाइल में ये अपडेट करें:

BEFORE:

from google.appengine.ext import vendor

# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)

सिर्फ़ इस कोड से, setuptools और grpcio का इस्तेमाल नहीं किया जा सकता. कुछ और लाइनें जोड़नी होंगी. इसलिए, appengine_config.py को इस तरह अपडेट करें:

AFTER:

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 क्लाइंट लाइब्रेरी के साथ काम करने के लिए, ज़रूरी बदलावों के बारे में ज़्यादा जानकारी बंडल की गई सेवाओं को माइग्रेट करने से जुड़े दस्तावेज़ में मिल सकती है.

app.yaml

appengine_config.py की तरह ही, app.yaml फ़ाइल को ऐसे वर्शन पर वापस लाना होगा जो Python 2 के साथ काम करता हो. आइए, ओरिजनल मॉड्यूल 20 app.yaml से शुरू करते हैं:

BEFORE:

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

पहले बताए गए setuptools और grpcio के अलावा, एक और डिपेंडेंसी (Identity Platform माइग्रेशन से सीधे तौर पर जुड़ी नहीं है) है. इसके लिए, Cloud Storage क्लाइंट लाइब्रेरी का इस्तेमाल करना ज़रूरी है. इसके लिए, तीसरे पक्ष के एक और बिल्ट-इन पैकेज, ssl की ज़रूरत होती है. app.yaml में, इन तीनों को नए libraries सेक्शन में जोड़ें. इसके लिए, उन पैकेज के "नवीनतम" उपलब्ध वर्शन चुनें:

AFTER:

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 के लिए, Python 3 requirements.txt में Google Auth, Cloud NDB, Cloud Resource Manager, और Firebase Admin SDK को जोड़ा है. Python 2 के लिए, यह स्थिति ज़्यादा मुश्किल है:

  • Resource Manager API, सैंपल ऐप्लिकेशन के लिए ज़रूरी allow-policy फ़ंक्शन उपलब्ध कराता है. अफ़सोस की बात है कि यह सुविधा, Cloud Resource Manager क्लाइंट लाइब्रेरी के Python 2 के फ़ाइनल वर्शन में उपलब्ध नहीं थी. (यह सिर्फ़ Python 3 वर्शन में उपलब्ध है.)
  • इसलिए, एपीआई से इस सुविधा को ऐक्सेस करने के लिए, किसी दूसरे तरीके की ज़रूरत होती है. इस समस्या को हल करने के लिए, एपीआई से कम्यूनिकेट करने के लिए Google API की लोअर-लेवल क्लाइंट लाइब्रेरी का इस्तेमाल करें. इस क्लाइंट लाइब्रेरी पर स्विच करने के लिए, google-cloud-resource-manager को निचले लेवल के google-api-python-client पैकेज से बदलें.
  • Python 2 अब काम नहीं करता. इसलिए, Module 21 के साथ काम करने वाले डिपेंडेंसी ग्राफ़ के लिए, कुछ पैकेज को खास वर्शन पर लॉक करना ज़रूरी है. कुछ पैकेज के बारे में बताना ज़रूरी है. भले ही, उन्हें Python 3 app.yaml में न बताया गया हो.

BEFORE:

flask

मॉड्यूल 20 requirements.txt से शुरू करके, इसे मॉड्यूल 21 ऐप्लिकेशन के लिए यहां दिए गए तरीके से अपडेट करें:

AFTER:

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

डिपेंडेंसी में बदलाव होने पर, पैकेज और वर्शन नंबर को रेपो में अपडेट कर दिया जाएगा. हालांकि, इस लेख को लिखते समय, app.yaml ऐप्लिकेशन के काम करने के लिए काफ़ी है.

कॉन्फ़िगरेशन से जुड़े अन्य अपडेट

अगर आपने इस कोडलैब में पहले बनाए गए lib फ़ोल्डर को नहीं मिटाया है, तो अभी मिटा दें. requirements.txt के नए अपडेट के साथ, lib में इन ज़रूरी शर्तों को इंस्टॉल करने के लिए, यह जाना-पहचाना निर्देश जारी करें:

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

अगर आपके डेवलपमेंट सिस्टम पर Python 2 और 3, दोनों इंस्टॉल हैं, तो आपको pip के बजाय pip2 का इस्तेमाल करना पड़ सकता है.

ऐप्लिकेशन कोड में बदलाव करना

अच्छी बात यह है कि ज़रूरी बदलावों में से ज़्यादातर, कॉन्फ़िगरेशन फ़ाइलों में किए जाते हैं. ऐप्लिकेशन कोड में सिर्फ़ एक बदलाव करना होगा. एपीआई को ऐक्सेस करने के लिए, Resource Manager क्लाइंट लाइब्रेरी के बजाय, Google API क्लाइंट लाइब्रेरी के निचले लेवल का इस्तेमाल करने के लिए, एक छोटा सा अपडेट करना होगा. templates/index.html वेब टेंप्लेट को अपडेट करने की कोई ज़रूरत नहीं है.

इंपोर्ट और इनिशियलाइज़ेशन को अपडेट करना

नीचे दिए गए उदाहरण में, Resource Manager क्लाइंट लाइब्रेरी (google.cloud.resourcemanager) को Google APIs क्लाइंट लाइब्रेरी (googleapiclient.discovery) से बदलने का तरीका बताया गया है:

BEFORE:

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

AFTER:

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 उपयोगकर्ताओं के लिए सहायता

लोअर-लेवल क्लाइंट लाइब्रेरी का इस्तेमाल करने के लिए, _get_gae_admins() में कुछ बदलाव करने होंगे. सबसे पहले, हम आपको यह बताएंगे कि क्या बदलाव हो रहा है. इसके बाद, हम आपको अपडेट करने के लिए पूरा कोड देंगे.

Python 2 कोड के लिए, google.auth.default() से मिले क्रेडेंशियल और प्रोजेक्ट आईडी, दोनों का इस्तेमाल करना ज़रूरी है. Python 3 में क्रेडेंशियल का इस्तेमाल नहीं किया जाता है. इसलिए, इसे अंडरस्कोर ( _ ) वाले डमी वैरिएबल को असाइन किया गया था. Python 2 वर्शन के लिए इसकी ज़रूरत होती है. इसलिए, अंडरस्कोर को CREDS में बदलें. इसके अलावा, Resource Manager API क्लाइंट बनाने के बजाय, आपको एपीआई सर्विस एंडपॉइंट बनाना होगा. यह एपीआई क्लाइंट की तरह ही होता है. इसलिए, हम वैरिएबल का नाम (rm_client) एक जैसा रख रहे हैं. एक अंतर यह है कि सर्विस एंडपॉइंट को इंस्टैंटिएट करने के लिए क्रेडेंशियल (CREDS) की ज़रूरत होती है.

ये बदलाव, नीचे दिए गए कोड में दिखते हैं:

BEFORE:

_, PROJ_ID = default(  # Application Default Credentials and project ID
        ['https://www.googleapis.com/auth/cloudplatformprojects.readonly'])
rm_client = resourcemanager.ProjectsClient()

AFTER:

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)

इनके बीच एक और अंतर यह है कि Resource Manager क्लाइंट लाइब्रेरी, allow-policy ऑब्जेक्ट दिखाती है. ये ऑब्जेक्ट, डॉटेड-एट्रिब्यूट नोटेशन का इस्तेमाल करते हैं. वहीं, लोअर-लेवल क्लाइंट लाइब्रेरी, Python डिक्शनरी दिखाती है. इनमें स्क्वेयर ब्रैकेट ( [ ] ) का इस्तेमाल किया जाता है. उदाहरण के लिए, Resource Manager क्लाइंट लाइब्रेरी के लिए binding.role का इस्तेमाल करें. वहीं, लोअर-लेवल लाइब्रेरी के लिए binding['role'] का इस्तेमाल करें. पहले वाले में "underscore_separated" नामों का इस्तेमाल किया जाता है, जबकि निचले लेवल की लाइब्रेरी में "CamelCased" नामों का इस्तेमाल किया जाता है. साथ ही, एपीआई पैरामीटर पास करने का तरीका भी थोड़ा अलग होता है.

इनके इस्तेमाल में अंतर यहां दिखाया गया है:

BEFORE:

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)

AFTER:

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'])

इन सभी बदलावों को एक साथ लागू करने के लिए, Python 3 के _get_gae_admins() को Python 2 के इस वर्शन से बदलें:

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() फ़ंक्शन को अपडेट करने की ज़रूरत नहीं है, क्योंकि यह _get_gae_admins() पर निर्भर करता है. _get_gae_admins() को पहले ही अपडेट किया जा चुका है.

Python 3 Module 21 ऐप्लिकेशन को Python 2 में बैकपोर्ट करने के लिए, ये बदलाव ज़रूरी हैं. बधाई हो! आपने अपडेट किए गए मॉड्यूल 21 के सैंपल ऐप्लिकेशन को ऐक्सेस कर लिया है! आपको पूरा कोड Module 21a repo folder में मिलेगा.

7. खास जानकारी/सफ़ाई

कोड लैब के आखिरी चरण में, यह पक्का करना होता है कि इस ऐप्लिकेशन को चलाने वाले प्रिंसिपल (उपयोगकर्ता या सेवा खाते) के पास ऐसा करने की ज़रूरी अनुमतियां हों. इसके बाद, अपने ऐप्लिकेशन को डिप्लॉय करें. इससे यह पुष्टि की जा सकेगी कि ऐप्लिकेशन, उम्मीद के मुताबिक काम कर रहा है और बदलाव आउटपुट में दिख रहे हैं.

आईएएम की अनुमति देने वाली नीति को पढ़ने की सुविधा

हमने आपको पहले, App Engine एडमिन उपयोगकर्ता के तौर पर पहचाने जाने के लिए ज़रूरी चार भूमिकाओं के बारे में बताया था. हालांकि, अब एक और भूमिका के बारे में जानना ज़रूरी है:

  • roles/viewer
  • roles/editor
  • roles/owner
  • roles/appengine.appAdmin
  • roles/resourcemanager.projectIamAdmin (आईएएम की अनुमति देने वाली नीति को ऐक्सेस करने वाले प्रिंसिपल के लिए)

roles/resourcemanager.projectIamAdmin भूमिका की मदद से, प्रिंसिपल यह तय कर सकते हैं कि कोई एंड-यूज़र, App Engine एडमिन की किसी भूमिका का सदस्य है या नहीं. roles/resourcemanager.projectIamAdmin में शामिल हुए बिना, Cloud Resource Manager API को कॉल करके अनुमति देने वाली नीति नहीं पाई जा सकती.

आपको यहां साफ़ तौर पर कोई कार्रवाई करने की ज़रूरत नहीं है, क्योंकि आपका ऐप्लिकेशन App Engine के डिफ़ॉल्ट सेवा खाते के तहत चलेगा. इस खाते को यह भूमिका अपने-आप मिल जाती है. अगर डेवलपमेंट के दौरान डिफ़ॉल्ट सेवा खाते का इस्तेमाल किया जाता है, तो हमारा सुझाव है कि आप उपयोगकर्ता के मैनेज किए गए सेवा खाते को बनाएं और उसका इस्तेमाल करें. साथ ही, अपने ऐप्लिकेशन के ठीक से काम करने के लिए ज़रूरी अनुमतियां दें. ऐसे सेवा खाते को सदस्यता देने के लिए, यह कमांड चलाएं:

$ 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 प्रोजेक्ट का आईडी है. साथ ही, USR_MGD_SVC_ACCT@PROJ_ID.iam.gserviceaccount.com, उपयोगकर्ता की ओर से मैनेज किया जाने वाला वह सेवा खाता है जिसे आपने अपने ऐप्लिकेशन के लिए बनाया है. यह कमांड, आपके प्रोजेक्ट के लिए अपडेट की गई IAM नीति को आउटपुट करती है. इसमें पुष्टि की जा सकती है कि सेवा खाते की सदस्यता roles/resourcemanager.projectIamAdmin में है. ज़्यादा जानकारी के लिए, रेफ़रंस दस्तावेज़ देखें. हम आपको फिर से बता दें कि इस कोडलैब में आपको यह कमांड जारी करने की ज़रूरत नहीं है. हालांकि, इसे अपने ऐप्लिकेशन को बेहतर बनाने के लिए, रेफ़रंस के तौर पर सेव करें.

ऐप्लिकेशन डिप्लॉय करना और उसकी पुष्टि करना

स्टैंडर्ड gcloud app deploy कमांड का इस्तेमाल करके, अपने ऐप्लिकेशन को क्लाउड पर अपलोड करें. डिप्लॉय करने के बाद, आपको Module 20 ऐप्लिकेशन की तरह ही लगभग सभी सुविधाएं दिखेंगी. हालांकि, आपने उपयोगकर्ता मैनेजमेंट के लिए, App Engine Users सेवा को Cloud Identity Platform (और Firebase Auth) से बदल दिया है:

3a83ae745121d70.png

मॉड्यूल 20 की तुलना में, आपको एक अंतर दिखेगा. लॉगिन पर क्लिक करने से, रीडायरेक्ट होने के बजाय एक पॉप-अप दिखता है. इसे यहां दिए गए कुछ स्क्रीनशॉट में दिखाया गया है. हालांकि, मॉड्यूल 20 की तरह ही, ब्राउज़र में रजिस्टर किए गए Google खातों की संख्या के आधार पर, यह थोड़ा अलग तरीके से काम करता है.

अगर ब्राउज़र में कोई भी उपयोगकर्ता रजिस्टर नहीं है या सिर्फ़ एक उपयोगकर्ता है जिसने अब तक साइन इन नहीं किया है, तो Google में साइन इन करने का सामान्य पॉप-अप दिखता है:

8437f5f3d489a942.png

अगर कोई उपयोगकर्ता आपके ब्राउज़र में रजिस्टर है, लेकिन वह किसी दूसरे डिवाइस पर साइन इन करता है, तो कोई डायलॉग नहीं दिखता. अगर डायलॉग दिखता है, तो वह तुरंत बंद हो जाता है. इसके बाद, ऐप्लिकेशन में साइन इन हो जाता है. इसमें उपयोगकर्ता का ईमेल पता और Logout बटन दिखता है.

कुछ डेवलपर, एक ही उपयोगकर्ता के लिए भी खाता चुनने की सुविधा उपलब्ध कराना चाहते हैं:

b75624cb68d94557.png

इसे लागू करने के लिए, वेब टेंप्लेट में provider.setCustomParameters({prompt: 'select_account'}); लाइन से कमेंट हटाएं. इसके बारे में पहले बताया जा चुका है.

अगर एक से ज़्यादा उपयोगकर्ता हैं, तो खाता चुनने का डायलॉग बॉक्स पॉप-अप होता है (नीचे देखें). अगर उपयोगकर्ता ने अब तक साइन इन नहीं किया है, तो उसे ऐसा करने के लिए कहा जाएगा. अगर पहले से साइन इन किया हुआ है, तो पॉप-अप हट जाता है और ऐप्लिकेशन में साइन इन हो जाता है.

c454455b6020d5e4.png

मॉड्यूल 21 में साइन इन करने की स्थिति, मॉड्यूल 20 के यूज़र इंटरफ़ेस जैसी दिखती है:

49ebe4dcc1eff11f.png

एडमिन ऐक्सेस वाले उपयोगकर्ता के साइन इन करने पर भी ऐसा ही होता है:

44302f35b39856eb.png

मॉड्यूल 21 के उलट, मॉड्यूल 20 हमेशा वेब टेंप्लेट के कॉन्टेंट के लिए लॉजिक को ऐक्सेस करता है. यह लॉजिक, ऐप्लिकेशन (सर्वर-साइड कोड) से मिलता है. मॉड्यूल 20 में यह गड़बड़ी है कि जब कोई व्यक्ति पहली बार ऐप्लिकेशन का इस्तेमाल करता है, तब एक विज़िट रजिस्टर होती है. इसके बाद, जब कोई व्यक्ति साइन इन करता है, तब दूसरी विज़िट रजिस्टर होती है.

मॉड्यूल 21 के लिए, लॉगिन लॉजिक सिर्फ़ वेब टेंप्लेट (क्लाइंट-साइड कोड) में होता है. यह तय करने के लिए कि कौनसी सामग्री दिखानी है, सर्वर-साइड ट्रिप की ज़रूरत नहीं होती. एंड-यूज़र के साइन इन करने के बाद, सर्वर को सिर्फ़ एक कॉल किया जाता है. यह कॉल, एडमिन उपयोगकर्ताओं की जांच करने के लिए किया जाता है. इसका मतलब है कि लॉगिन और लॉगआउट करने से, अतिरिक्त विज़िट रजिस्टर नहीं होती हैं. इसलिए, उपयोगकर्ता को मैनेज करने से जुड़ी कार्रवाइयों के लिए, हाल की विज़िट की सूची में कोई बदलाव नहीं होता. ऊपर दिए गए स्क्रीनशॉट में देखें कि एक ही सेट की चार विज़िट, कई उपयोगकर्ता लॉगिन में दिख रही हैं.

मॉड्यूल 20 के स्क्रीनशॉट में, इस कोडलैब की शुरुआत में "डबल-विज़िट बग" के बारे में बताया गया है. साइन-इन या साइन-आउट करने की हर कार्रवाई के लिए, विज़िट के अलग-अलग लॉग दिखाए जाते हैं. तारीख के हिसाब से क्रम में दिखाए गए हर स्क्रीनशॉट के लिए, सबसे हाल ही की विज़िट के टाइमस्टैंप देखें.

व्यवस्थित करें

सामान्य

अगर आपको अभी और काम नहीं करना है, तो हमारा सुझाव है कि आप अपने App Engine ऐप्लिकेशन को बंद कर दें, ताकि आपसे शुल्क न लिया जाए. हालांकि, अगर आपको कुछ और टेस्ट या एक्सपेरिमेंट करने हैं, तो App Engine प्लैटफ़ॉर्म पर मुफ़्त कोटा उपलब्ध है. इसलिए, जब तक आप इस्तेमाल की उस सीमा से ज़्यादा नहीं होते हैं, तब तक आपसे कोई शुल्क नहीं लिया जाएगा. यह शुल्क कंप्यूट के लिए है. हालांकि, App Engine की सेवाओं के लिए भी शुल्क लिया जा सकता है. इसलिए, ज़्यादा जानकारी के लिए कीमत वाला पेज देखें. अगर इस माइग्रेशन में अन्य क्लाउड सेवाएं शामिल हैं, तो उनके लिए अलग से बिल भेजा जाता है. अगर लागू हो, तो दोनों ही मामलों में, नीचे दिया गया "इस कोडलैब के लिए खास जानकारी" सेक्शन देखें.

पूरी जानकारी के लिए बता दें कि App Engine जैसे Google Cloud के सर्वरलेस कंप्यूट प्लैटफ़ॉर्म पर डिप्लॉय करने से, बिल्ड और स्टोरेज के लिए मामूली शुल्क लगता है. Cloud Build का अपना मुफ़्त कोटा होता है. साथ ही, Cloud Storage का भी अपना मुफ़्त कोटा होता है. उस इमेज को सेव करने के लिए, स्टोरेज कोटा का कुछ हिस्सा इस्तेमाल किया जाता है. हालांकि, ऐसा हो सकता है कि आपके देश/इलाके में बिना किसी शुल्क के स्टोरेज इस्तेमाल करने की सुविधा उपलब्ध न हो. इसलिए, स्टोरेज के इस्तेमाल पर नज़र रखें, ताकि संभावित लागत को कम किया जा सके. Cloud Storage के कुछ "फ़ोल्डर" की समीक्षा करनी चाहिए. इनमें ये शामिल हैं:

  • 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
  • ऊपर दिए गए स्टोरेज लिंक, आपके PROJECT_ID और LOCation पर निर्भर करते हैं. उदाहरण के लिए, अगर आपका ऐप्लिकेशन अमेरिका में होस्ट किया गया है, तो "us" लिंक का इस्तेमाल किया जाएगा.

दूसरी ओर, अगर आपको इस ऐप्लिकेशन या माइग्रेशन से जुड़े अन्य कोडलैब का इस्तेमाल नहीं करना है और आपको सब कुछ पूरी तरह से मिटाना है, तो अपना प्रोजेक्ट बंद करें.

इस कोडलैब के लिए खास तौर पर

यहां दी गई सेवाएं, इस कोड सीखने की लैब के लिए खास तौर पर बनाई गई हैं. ज़्यादा जानकारी के लिए, हर प्रॉडक्ट का दस्तावेज़ देखें:

  • App Engine Datastore सेवा, Cloud Datastore (Cloud Firestore in Datastore mode) से मिलती है. इसमें भी बिना शुल्क वाली सेवा उपलब्ध है. ज़्यादा जानकारी के लिए, इसका कीमत वाला पेज देखें.
  • Cloud Identity Platform का इस्तेमाल कुछ हद तक "मुफ़्त" है. यह इस बात पर निर्भर करता है कि इसकी कौनसी सेवाओं का इस्तेमाल किया जा रहा है. ज़्यादा जानकारी के लिए, कीमत की जानकारी देने वाला पेज देखें.
  • Cloud Resource Manager API का इस्तेमाल ज़्यादातर मुफ़्त में किया जा सकता है. इस बारे में ज़्यादा जानकारी कीमत वाले पेज पर दी गई है.

अगले चरण

इस ट्यूटोरियल के अलावा, माइग्रेशन के अन्य मॉड्यूल भी उपलब्ध हैं. इनमें लेगसी बंडल की गई सेवाओं से माइग्रेट करने पर फ़ोकस किया गया है. इनमें ये शामिल हैं:

App Engine अब Google Cloud में सर्वरलेस प्लैटफ़ॉर्म नहीं है. अगर आपके पास कोई छोटा App Engine ऐप्लिकेशन है या ऐसा ऐप्लिकेशन है जिसमें सीमित सुविधाएं हैं और आपको उसे स्टैंडअलोन माइक्रोसेवा में बदलना है या आपको किसी मोनोलिथिक ऐप्लिकेशन को फिर से इस्तेमाल किए जा सकने वाले कई कॉम्पोनेंट में बांटना है, तो Cloud Functions पर माइग्रेट करने के लिए ये अच्छी वजहें हैं. अगर कंटेनर बनाने की प्रोसेस, ऐप्लिकेशन डेवलपमेंट वर्कफ़्लो का हिस्सा बन गई है, तो Cloud Run पर माइग्रेट करें. खास तौर पर, अगर इसमें सीआई/सीडी (लगातार इंटिग्रेशन/लगातार डिलीवरी या डिप्लॉयमेंट) पाइपलाइन शामिल है. इन स्थितियों के बारे में यहां दिए गए मॉड्यूल में बताया गया है:

  • App Engine से Cloud Functions पर माइग्रेट करना: मॉड्यूल 11 देखें
  • App Engine से Cloud Run पर माइग्रेट करना: Docker की मदद से अपने ऐप्लिकेशन को कंटेनर में बदलने के लिए, मॉड्यूल 4 देखें. इसके अलावा, कंटेनर, Docker की जानकारी या Dockerfile के बिना ऐसा करने के लिए, मॉड्यूल 5 देखें

किसी दूसरे सर्वरलेस प्लैटफ़ॉर्म पर स्विच करना ज़रूरी नहीं है. हमारा सुझाव है कि कोई भी बदलाव करने से पहले, अपने ऐप्लिकेशन और इस्तेमाल के उदाहरणों के लिए सबसे सही विकल्पों पर विचार करें.

अगले माइग्रेशन मॉड्यूल के तौर पर किसी भी मॉड्यूल को चुना जा सकता है. हालांकि, Serverless Migration Station का पूरा कॉन्टेंट (कोड लैब, वीडियो, सोर्स कोड [अगर उपलब्ध हो]) इसके ओपन सोर्स रेपो में ऐक्सेस किया जा सकता है. रेपो के README में यह भी बताया गया है कि किन माइग्रेशन पर विचार करना चाहिए. साथ ही, माइग्रेशन मॉड्यूल के "क्रम" के बारे में भी बताया गया है.

8. अन्य संसाधन

यहां उन डेवलपर के लिए अतिरिक्त संसाधन दिए गए हैं जो इस या इससे जुड़े माइग्रेशन मॉड्यूल के बारे में ज़्यादा जानना चाहते हैं. यहां इस कॉन्टेंट के बारे में सुझाव/राय दी जा सकती है या शिकायत की जा सकती है. साथ ही, कोड के लिंक और अलग-अलग दस्तावेज़ देखे जा सकते हैं.

कोडलैब से जुड़ी समस्याएं/सुझाव/राय

अगर आपको इस कोडलैब में कोई समस्या मिलती है, तो कृपया शिकायत दर्ज करने से पहले अपनी समस्या खोजें. नई समस्याएं खोजने और बनाने के लिए लिंक:

माइग्रेशन के लिए उपलब्ध संसाधन

मॉड्यूल 20 (START) और मॉड्यूल 21 (FINISH) के लिए, रेपो फ़ोल्डर के लिंक यहां दी गई टेबल में देखे जा सकते हैं.

कोडलैब

Python 2

Python 3

मॉड्यूल 20

code

(लागू नहीं)

मॉड्यूल 21 (यह कोडलैब)

code

code

ऑनलाइन रेफ़रंस

इस ट्यूटोरियल के लिए काम के संसाधन यहां दिए गए हैं:

Cloud Identity Platform और Cloud Marketplace

Cloud Resource Manager, Cloud IAM, Firebase Admin SDK

App Engine Users, App Engine NDB, Cloud NDB, Cloud Datastore

माइग्रेशन मॉड्यूल के अन्य रेफ़रंस

App Engine माइग्रेशन

App Engine प्लैटफ़ॉर्म

Cloud SDK

क्लाउड से जुड़ी अन्य जानकारी

वीडियो

लाइसेंस

इस काम के लिए, Creative Commons एट्रिब्यूशन 2.0 जेनेरिक लाइसेंस के तहत लाइसेंस मिला है.