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

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

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

इस कोडलैब का मकसद Python 2 App Engine के डेवलपर को यह बताना है कि App Engine उपयोगकर्ता एपीआई/सेवा से Cloud Identity प्लैटफ़ॉर्म (GCIP) पर माइग्रेट कैसे करें. Datastore के ऐक्सेस (मुख्य तौर पर माइग्रेशन मॉड्यूल 2 में शामिल किया गया है) के लिए, App Engine NDB से Cloud NDB पर इंप्लिसिट माइग्रेशन. इसके अलावा, Python 3 में अपग्रेड करने की सुविधा भी उपलब्ध है.

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

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

  • App Engine उपयोगकर्ता सेवा के इस्तेमाल को Cloud Identity प्लैटफ़ॉर्म से बदलें
  • App Engine NDB के इस्तेमाल को Cloud NDB से बदलें (मॉड्यूल 2 भी देखें)
  • Firebase पुष्टि का इस्तेमाल करके, पहचान की पुष्टि करने वाली अलग-अलग कंपनियां सेटअप करें
  • प्रोजेक्ट IAM की जानकारी पाने के लिए, Cloud Resource Manager API का इस्तेमाल करना
  • उपयोगकर्ताओं की जानकारी पाने के लिए, Firebase एडमिन SDK का इस्तेमाल करना
  • सैंपल ऐप्लिकेशन को Python 3 में पोर्ट करना

आपको इनकी ज़रूरत होगी

सर्वे

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

सिर्फ़ इसे पढ़ें इसे पढ़ें और कसरतों को पूरा करें

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

शुरुआती इंटरमीडिएट कुशल

Google Cloud की सेवाएं इस्तेमाल करने का आपका अनुभव कैसा रहा?

शुरुआती इंटरमीडिएट कुशल

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

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

Identity Platform, Firebase से पुष्टि करने की सुविधा पर आधारित होता है. इसमें कई एंटरप्राइज़ सुविधाएं शामिल होती हैं. जैसे: बहु-स्तरीय पुष्टि (MFA) और OIDC एसएएमएल एसएसओ (SSO) की सुविधा, मल्टी-टेनेंसी, 99.95% एसएलए वगैरह. इन अंतरों को Identity Platform और Firebase से पुष्टि करने वाले प्रॉडक्ट की तुलना करने वाले पेज पर भी हाइलाइट किया गया है. उपयोगकर्ता सेवा में मिलने वाली सुविधाओं की तुलना में, दोनों प्रॉडक्ट में काफ़ी ज़्यादा सुविधाएं हैं.

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

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

इस ट्यूटोरियल में ये चरण बताए गए हैं:

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

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

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

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

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

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

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

2. बेसलाइन ऐप्लिकेशन का नमूना डाउनलोड करें

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

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

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

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

मॉड्यूल 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 के साथ सेट करें.
  4. gcloud app deploy के साथ सैंपल ऐप्लिकेशन डिप्लॉय करें
  5. पक्का करें कि ऐप्लिकेशन बिना किसी गड़बड़ी के ठीक से काम कर रहा हो. अगर आपने मॉड्यूल 20 कोडलैब (कोड बनाना सीखना) पूरा कर लिया है, तो ऐप्लिकेशन सबसे ऊपर उपयोगकर्ता की लॉगिन जानकारी (उपयोगकर्ता ईमेल, संभावित "एडमिन बैज", और लॉगिन/लॉगआउट बटन) दिखाता है. साथ ही, सबसे हाल की विज़िट (नीचे दिखाया गया है) भी दिखाता है.

907e64c19ef964f8.png

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

ad7b59916b69a035.png

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

867bcb3334149e4.png

4. नए Google Cloud API/सेवाएं चालू करें

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

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

लागत

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

उपयोगकर्ता आपकी प्राथमिकता के हिसाब से, Cloud Console या कमांड लाइन (gcloud कमांड के ज़रिए, Cloud SDK टूल का हिस्सा) से Cloud API को चालू करते हैं. चलिए, 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.

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

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

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

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

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

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

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

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

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

appengine_config.py

  • Python 3 में अपग्रेड करने पर, appengine_config.py को मिटा दें
  • अगर Identity प्लैटफ़ॉर्म पर मॉडर्न बनाने की योजना है, लेकिन 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 का इस्तेमाल करना है, तो फ़िलहाल कोई कार्रवाई न करें.

पहले:

runtime: python27
threadsafe: yes
api_version: 1

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

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

बाद में:

runtime: python310

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

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

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

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

इंपोर्ट और शुरू करने की प्रोसेस अपडेट करें

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

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

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

पहले:

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

app = Flask(__name__)

बाद में:

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(), मौजूदा Cloud IAM अनुमति देने से जुड़ी नीति को फ़ेच करने के लिए, Resource Manager API को कॉल करता है. अनुमति देने वाली नीति में यह तय किया जाता है कि किन प्रिंसिपलों को दी जाने वाली भूमिकाएं, जैसे कि उपयोगकर्ता, सेवा खाते वगैरह को दी जाती हैं. सेटअप में ये शामिल हैं:

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

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

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

  • 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

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

फ़ंक्शन का मुख्य मुख्य हिस्सा, एडमिन उपयोगकर्ताओं (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 आईडी टोकन को पोस्ट के मुख्य हिस्से में is_admin() को पास किया जाता है, जो इसे हेडर से हासिल करके इसकी पुष्टि करने के लिए Firebase एडमिन SDK टूल को कॉल करता है. अगर यह मान्य उपयोगकर्ता है, तो उसका ईमेल पता निकालें और देखें कि वह खाते का एडमिन है या नहीं.
  4. इसके बाद, बूलियन नतीजा, टेंप्लेट में 200 के तौर पर वापस आ जाता है.

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

@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 पुष्टि करने की प्रोसेस शुरू करें और App Engine के एडमिन को कैश मेमोरी में सेव करें

हम 'Firebase ऑथेंट' को उस जगह के पास शुरू कर सकते थे जहां से फ़्लास्क ऐप्लिकेशन शुरू किया गया है और क्लाउड एनडीबी एपीआई क्लाइंट बनाया गया है. हालांकि, जब तक सारे एडमिन कोड तय नहीं हो जाते, हम अब वहीं हैं. इसी तरह, अब _get_gae_admins() तय हो गया है, इसलिए इसे एडमिन उपयोगकर्ताओं की सूची को कैश मेमोरी में सेव करने के लिए कॉल करें.

is_admin() के फ़ंक्शन के मुख्य हिस्से के ठीक नीचे ये लाइनें जोड़ें:

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

डेटा मॉडल के अपडेट पर जाएं

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

पहले:

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)

बाद में:

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 उपयोगकर्ताओं की सेवा, सर्वर साइड है. वहीं, Firebase Auth और Cloud Identity Platform मुख्य रूप से क्लाइंट-साइड होते हैं. इस वजह से, मॉड्यूल 20 ऐप्लिकेशन में मौजूद यूज़र मैनेजमेंट कोड का ज़्यादातर हिस्सा मॉड्यूल 21 वेब टेंप्लेट में चला जाएगा.

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

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

पहले:

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

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

बाद में:

@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 ऑथराइज़ेशन पर ले जाना. साथ ही, उस सभी कोड के कुछ पोर्ट को ट्रांसफ़र करना जिसे हमने JavaScript में शामिल किया है. हमने देखा है कि main.py की वैल्यू में गिरावट आई है. इसलिए, templates/index.html में भी आपको मिलती-जुलती बढ़ोतरी देखने को मिल सकती है.

पहले:

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

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

बाद में:

<!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 से पुष्टि कराने, पुष्टि करने वाले सेवा देने वाले के तौर पर Google, साइन इन और साइन आउट करने, और पुष्टि करने की स्थिति को मैनेज करते हैं, वे "कॉलबैक" में बदलाव करते हैं ये सभी Firebase पुष्टि मॉड्यूल से इंपोर्ट किए जाते हैं:

<!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 कॉन्फ़िगरेशन

इस ट्यूटोरियल के लिए आइडेंटिटी प्लैटफ़ॉर्म सेटअप करने के दौरान, आपने 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 और User API से Cloud NDB और Identity Platform पर स्विच करने के साथ-साथ, Python 3 पर अपग्रेड करने के लिए, ऐप्लिकेशन और वेब टेंप्लेट में ज़रूरी बदलाव पूरे होते हैं. मॉड्यूल 21 के नए सैंपल ऐप्लिकेशन को आज़माने के लिए बधाई! हमारा वर्शन मॉड्यूल 21b रेपो फ़ोल्डर में समीक्षा के लिए उपलब्ध है.

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

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

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

मॉड्यूल 21 ऐप्लिकेशन का ठीक से काम करने वाला Python 2 वर्शन बनाने के लिए, आपको इन चीज़ों की ज़रूरत होगी:

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

आइए, अब कॉन्फ़िगरेशन से शुरुआत करते हैं.

appengine_config.py को पुनर्स्थापित करें

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

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

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

पहले:

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 को अपडेट करें, ताकि वह कुछ ऐसा दिखे:

बाद में:

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)

क्लाउड क्लाइंट लाइब्रेरी के काम करने के लिए ज़रूरी बदलावों के बारे में ज़्यादा जानकारी, बंडल की गई सेवाओं के दस्तावेज़ में मिल सकती है.

app.yaml

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

पहले:

runtime: python27
threadsafe: yes
api_version: 1

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

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

बाद में:

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 एडमिन SDK को जोड़ा है. Python 2 के लिए स्थिति ज़्यादा जटिल है:

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

पहले:

flask

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

बाद में:

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 का इस्तेमाल करना पड़ सकता है.

ऐप्लिकेशन कोड बदलें

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

इंपोर्ट करने और शुरू करने की प्रोसेस अपडेट करना

संसाधन मैनेजर क्लाइंट लाइब्रेरी (google.cloud.resourcemanager) को Google API क्लाइंट लाइब्रेरी (googleapiclient.discovery) से बदलें, जैसा कि नीचे दिखाया गया है:

पहले:

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

बाद में:

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

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

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

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

पहले:

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

बाद में:

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 क्लाइंट लाइब्रेरी, अनुमति वाली नीति के ऐसे ऑब्जेक्ट दिखाती है जो डॉट-एट्रिब्यूट नोटेशन का इस्तेमाल करते हैं. वहीं, लोअर-लेवल की क्लाइंट लाइब्रेरी Python डिक्शनरी दिखाती है, जिसमें स्क्वेयर ब्रैकेट ( [ ] ) का इस्तेमाल किया जाता है. उदाहरण के लिए, रिसोर्स मैनेजर क्लाइंट लाइब्रेरी के लिए binding.role का इस्तेमाल करें, जबकि निचले लेवल की लाइब्रेरी के लिए binding['role'] का इस्तेमाल करें. पहले वाले शब्द में "अंडरस्कोर_सेपरेटेड" का भी इस्तेमाल होता है नाम बनाम लोअर-लेवल लाइब्रेरी जो "CamelCased" को प्राथमिकता देते हैं के नाम के साथ एपीआई पैरामीटर में पास करने का थोड़ा अलग तरीका बताया है.

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

पहले:

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)

बाद में:

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() पर निर्भर है.

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

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 के स्टैंडर्ड निर्देश का इस्तेमाल करके, अपने ऐप्लिकेशन को क्लाउड पर अपलोड करें. डिप्लॉय किए जाने के बाद, आपको करीब मॉड्यूल 20 ऐप्लिकेशन से मिलती-जुलती सुविधा दिखेगी. हालांकि, यूज़र मैनेजमेंट के लिए, आपने App Engine उपयोगकर्ताओं की सेवा को Cloud Identity Platform (और Firebase पुष्टि) से बदल दिया है:

3a83ae745121d70.png

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

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

8437f5f3d489a942.png

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

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

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 Storage की तरह Cloud Build का अपना अलग कोटा होता है. उस इमेज का स्टोरेज, उसके कुछ हिस्से का इस्तेमाल करता है. हालांकि, हो सकता है कि आप किसी ऐसे क्षेत्र में हों जहां ऐसा कोई फ़्री टीयर उपलब्ध न हो. इसलिए, संभावित लागत को कम करने के लिए, अपने स्टोरेज के इस्तेमाल को ध्यान में रखें. 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 और LOCडेटा के हिसाब से तय होते हैं. उदाहरण के लिए, "us" अगर आपका ऐप्लिकेशन अमेरिका में होस्ट किया जाता है.

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

इस कोडलैब के लिए खास

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

अगले चरण

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

  • मॉड्यूल 2: App Engine ndb से Cloud NDB पर माइग्रेट करें
  • मॉड्यूल 7-9: App Engine टास्क सूची (पुश टास्क) से क्लाउड टास्क में माइग्रेट करें
  • मॉड्यूल 12-13: App Engine Memcache से Cloud Memorystore में माइग्रेट करना
  • मॉड्यूल 15-16: App Engine Blobstore से Cloud Storage में माइग्रेट करना
  • मॉड्यूल 18-19: App Engine टास्क सूची (टास्क पुल करें) से Cloud Pub/Sub में माइग्रेट करें

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

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

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

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

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

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

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

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

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

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

Codelab

Python 2

Python 3

मॉड्यूल 20

कोड

(लागू नहीं)

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

कोड

कोड

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

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

Cloud Identity Platform और Cloud Marketplace

Cloud Resource Manager, Cloud IAM, Firebase एडमिन SDK

App Engine के उपयोगकर्ता, App Engine NDB, Cloud NDB, Cloud Datastore

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

App Engine माइग्रेशन

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

Cloud SDK

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

वीडियो

लाइसेंस

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