ওয়েব সার্ভার অ্যাপ্লিকেশনের জন্য OAuth 2.0 ব্যবহার করা

Google API অ্যাক্সেস করার জন্য OAuth 2.0 অনুমোদন প্রয়োগ করতে, ওয়েব সার্ভার অ্যাপ্লিকেশন কীভাবে Google API ক্লায়েন্ট লাইব্রেরি বা Google OAuth 2.0 এন্ডপয়েন্ট ব্যবহার করে তা এই ডকুমেন্টে ব্যাখ্যা করা হয়েছে।

OAuth 2.0 ব্যবহারকারীদের তাদের ইউজারনেম, পাসওয়ার্ড এবং অন্যান্য তথ্য গোপন রেখে একটি অ্যাপ্লিকেশনের সাথে নির্দিষ্ট ডেটা শেয়ার করতে দেয়। যেমন, কোনও অ্যাপ্লিকেশন ব্যবহারকারীর Google Drive-এ ফাইল সেভ করার অনুমতি পেতে OAuth 2.0 ব্যবহার করতে পারে।

এই OAuth 2.0 ফ্লো বিশেষভাবে ব্যবহারকারীর অনুমোদনের জন্য। এটি এমন অ্যাপ্লিকেশনের জন্য ডিজাইন করা হয়েছে যা গোপনীয় তথ্য স্টোর করতে এবং স্টেট বজায় রাখতে পারে। ব্যবহারকারী অ্যাপ্লিকেশনটির সাথে ইন্টার‍্যাক্ট করার সময় বা ব্যবহারকারী অ্যাপ্লিকেশন ছেড়ে যাওয়ার পরে, যথাযথভাবে অনুমোদিত ওয়েব সার্ভার অ্যাপ্লিকেশন API অ্যাক্সেস করতে পারে।

এছাড়াও, ওয়েব সার্ভার অ্যাপ্লিকেশনগুলি প্রায়শই API অনুরোধ অনুমোদন করার জন্য পরিষেবা অ্যাকাউন্ট ব্যবহার করে, বিশেষ করে ব্যবহারকারী-নির্দিষ্ট ডেটার পরিবর্তে প্রোজেক্ট-ভিত্তিক ডেটা অ্যাক্সেস করার জন্য Cloud API কল করার সময়। ওয়েব সার্ভার অ্যাপ্লিকেশন ব্যবহারকারীর অনুমোদনের সাথে পরিষেবা অ্যাকাউন্ট ব্যবহার করতে পারে।

ক্লায়েন্ট লাইব্রেরি

এই পৃষ্ঠায় ভাষা-নির্দিষ্ট উদাহরণে OAuth 2.0 অনুমোদন প্রয়োগ করতে Google API ক্লায়েন্ট লাইব্রেরি ব্যবহার করা হয়। কোড স্যাম্পেল রান করাতে, আপনাকে প্রথমে নিজের ভাষার জন্য ক্লায়েন্ট লাইব্রেরি ইনস্টল করতে হবে।

আপনার অ্যাপ্লিকেশনের OAuth 2.0 ফ্লো ম্যানেজ করার জন্য Google API ক্লায়েন্ট লাইব্রেরি ব্যবহার করলে, ক্লায়েন্ট লাইব্রেরি এমন অনেক কাজ করে যা অন্যথায় অ্যাপ্লিকেশনকে নিজে করতে হত। যেমন, এটি নির্ধারণ করে যে অ্যাপ্লিকেশন কখন স্টোর করা অ্যাক্সেস টোকেন ব্যবহার বা রিফ্রেশ করতে পারে এবং কখন অ্যাপ্লিকেশনকে আবার সম্মতি নিতে হবে। এছাড়াও, ক্লায়েন্ট লাইব্রেরি সঠিক রিডাইরেক্ট URL তৈরি করে এবং রিডাইরেক্ট হ্যান্ডলার প্রয়োগ করতে সাহায্য করে যা অ্যাক্সেস টোকেনের জন্য অথরাইজেশন কোড এক্সচেঞ্জ করে।

সার্ভার-সাইড অ্যাপ্লিকেশনের জন্য Google API ক্লায়েন্ট লাইব্রেরি নিম্নলিখিত ভাষায় উপলভ্য:

পূর্বশর্ত

আপনার প্রোজেক্টের জন্য API চালু করা

Google API কল করে এমন যেকোনও অ্যাপ্লিকেশনকে API কনসোলে সেইসব API চালু করতে হবে।

আপনার প্রোজেক্টের জন্য API চালু করতে:

  1. Google API Console-এ API লাইব্রেরি খুলুন।
  2. প্রম্পট করা হলে, কোনও প্রোজেক্ট বেছে নিন অথবা নতুন একটি তৈরি করুন।
  3. API লাইব্রেরিতে উপলভ্য সব API-এর তালিকা দেওয়া আছে, এগুলিকে প্রোডাক্ট ফ্যামিলি ও জনপ্রিয়তার ভিত্তিতে গ্রুপ করা হয়েছে। আপনি যে API চালু করতে চান সেটি তালিকায় দেখতে না পেলে, সার্চ করে সেটি খুঁজে নিন অথবা যে প্রোডাক্ট ফ্যামিলির অন্তর্গত সেটিতে সব দেখুন বিকল্পে ক্লিক করুন।
  4. আপনি যে API চালু করতে চান সেটি বেছে নিন, তারপরে চালু করুন বোতামে ক্লিক করুন।
  5. প্রম্পট করা হলে, বিলিং চালু করুন।
  6. প্রম্পট করা হলে, API-এর পরিষেবার শর্তাবলী পড়ে সম্মতি দিন।

অনুমোদনের ক্রেডেনশিয়াল তৈরি করা

Google API অ্যাক্সেস করার জন্য OAuth 2.0 ব্যবহার করে এমন যেকোনও অ্যাপ্লিকেশনের কাছে অবশ্যই অনুমোদনের ক্রেডেনশিয়াল থাকতে হবে যা Google-এর OAuth 2.0 সার্ভারে অ্যাপ্লিকেশনটিকে শনাক্ত করে। আপনার প্রোজেক্টের জন্য কীভাবে ক্রেডেনশিয়াল তৈরি করবেন তা নিচের ধাপগুলি থেকে জানতে পারবেন। আপনার অ্যাপ্লিকেশন সেই প্রোজেক্টের জন্য চালু করা API অ্যাক্সেস করতে ক্রেডেনশিয়াল ব্যবহার করতে পারবে।

  1. ক্লায়েন্ট পৃষ্ঠায় যান।
  2. ক্লায়েন্ট তৈরি করুন বিকল্পে ক্লিক করুন।
  3. আবেদনের ধরন হিসেবে ওয়েব অ্যাপ্লিকেশন বেছে নিন।
  4. ফর্ম পূরণ করে তৈরি করুন বিকল্পে ক্লিক করুন। PHP, Java, Python, Ruby এবং .NET-এর মতো ভাষা ও ফ্রেমওয়ার্ক ব্যবহার করে এমন অ্যাপ্লিকেশনকে অবশ্যই অনুমোদিত রিডাইরেক্ট URI উল্লেখ করতে হবে। রিডাইরেক্ট URI হল এন্ডপয়েন্ট যেখানে OAuth 2.0 সার্ভার উত্তর পাঠাতে পারে। এইসব এন্ডপয়েন্টকে অবশ্যই Google-এর যাচাইকরণ সংক্রান্ত নিয়ম মেনে চলতে হবে।

    পরীক্ষা করার জন্য, আপনি লোকাল মেশিনকে রেফার করে এমন URI উল্লেখ করতে পারেন, যেমন http://localhost:8080। এই ডকুমেন্টের সব উদাহরণে রিডাইরেক্ট URI হিসেবে http://localhost:8080 ব্যবহার করা হয়েছে।

    আমরা সাজেস্ট করি যে আপনি আপনার অ্যাপের অথ এন্ডপয়েন্ট ডিজাইন করুন যাতে আপনার অ্যাপ্লিকেশন পৃষ্ঠার অন্যান্য রিসোর্সে অথরাইজেশন কোড প্রকাশ না করে।

আপনার ক্রেডেনশিয়াল তৈরি করার পরে, API কনসোল থেকে client_secret.json ফাইলটি ডাউনলোড করুন। শুধুমাত্র আপনার অ্যাপ্লিকেশন অ্যাক্সেস করতে পারে এমন কোনও লোকেশনে ফাইলটি নিরাপদে স্টোর করুন।

অ্যাক্সেস স্কোপ শনাক্ত করা

স্কোপ আপনার অ্যাপ্লিকেশনকে শুধুমাত্র প্রয়োজনীয় রিসোর্স অ্যাক্সেস করার অনুরোধ করতে দেয় এবং ব্যবহারকারীদের আপনার অ্যাপ্লিকেশনকে দেওয়া অ্যাক্সেসের পরিমাণ নিয়ন্ত্রণ করতে দেয়। তাই, অনুরোধ করা স্কোপের সংখ্যা এবং ব্যবহারকারীর সম্মতি পাওয়ার সম্ভাবনার মধ্যে বিপরীত সম্পর্ক থাকতে পারে।

OAuth 2.0 অনুমোদন প্রয়োগ করা শুরু করার আগে, আমরা সাজেস্ট করি যে আপনার অ্যাপকে অ্যাক্সেস করার জন্য যেসব স্কোপের অনুমতি নিতে হবে সেগুলি শনাক্ত করুন।

এছাড়াও, আমরা সাজেস্ট করি যে আপনার অ্যাপ্লিকেশন যেন ইনক্রিমেন্টাল অথরাইজেশন প্রসেসের মাধ্যমে অথরাইজেশন স্কোপ অ্যাক্সেস করার অনুরোধ করে, যেখানে আপনার অ্যাপ্লিকেশন প্রাসঙ্গিক ব্যবহারকারীর ডেটা অ্যাক্সেস করার অনুরোধ করে। এই পেশাদার পদ্ধতি ব্যবহারকারীদের আরও সহজে বুঝতে সাহায্য করে যে আপনার অ্যাপ্লিকেশন কেন অ্যাক্সেসের অনুরোধ করছে।

OAuth 2.0 API স্কোপ ডকুমেন্টে স্কোপের সম্পূর্ণ তালিকা রয়েছে যা আপনি Google API অ্যাক্সেস করতে ব্যবহার করতে পারেন।

ভাষা-নির্দিষ্ট প্রয়োজনীয়তা

এই ডকুমেন্টের যেকোনও কোড স্যাম্পেল রান করতে, আপনার একটি Google অ্যাকাউন্ট, ইন্টারনেট অ্যাক্সেস এবং একটি ওয়েব ব্রাউজার প্রয়োজন হবে। আপনি যদি API ক্লায়েন্ট লাইব্রেরির মধ্যে কোনও একটি ব্যবহার করেন, তাহলে নিম্নলিখিত বিভাগে ভাষা-নির্দিষ্ট প্রয়োজনীয়তাও দেখুন।

PHP

এই ডকুমেন্টে PHP কোড স্যাম্পেল রান করতে, আপনার এগুলি প্রয়োজন হবে:

  • কমান্ড-লাইন ইন্টারফেস (CLI) ও JSON এক্সটেনশন ইনস্টল করা PHP 8.0 বা তার পরের যেকোনও ভার্সন।
  • Composer ডিপেন্ডেন্সি ম্যানেজমেন্ট টুল।
  • PHP-এর জন্য Google API ক্লায়েন্ট লাইব্রেরি:

    composer require google/apiclient:^2.15.0

আরও তথ্যের জন্য PHP-এর জন্য Google API ক্লায়েন্ট লাইব্রেরি দেখুন।

Python

এই ডকুমেন্টে Python কোড স্যাম্পেল রান করতে, আপনার এগুলি প্রয়োজন হবে:

  • Python 3.7 বা তার পরবর্তী ভার্সন
  • pip প্যাকেজ ম্যানেজমেন্ট টুল।
  • Python 2.0 রিলিজের জন্য Google API ক্লায়েন্ট লাইব্রেরি:
    pip install --upgrade google-api-python-client
  • ব্যবহারকারীকে অনুমোদন করার জন্য google-auth, google-auth-oauthlib এবং google-auth-httplib2।
    pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
  • Flask Python ওয়েব অ্যাপ্লিকেশন ফ্রেমওয়ার্ক।
    pip install --upgrade flask
  • requests HTTP লাইব্রেরি।
    pip install --upgrade requests

আপনি Python ও সংশ্লিষ্ট মাইগ্রেশন গাইড আপগ্রেড করতে না পারলে, Google API Python ক্লায়েন্ট লাইব্রেরির রিলিজ নোট ভাল করে দেখে নিন।

Ruby

এই ডকুমেন্টে Ruby কোড স্যাম্পেল চালানোর জন্য আপনার এগুলি প্রয়োজন হবে:

  • Ruby 2.6 বা তার পরবর্তী যেকোনও ভার্সন
  • Ruby-এর জন্য Google Auth লাইব্রেরি:

    gem install googleauth
  • Drive এবং Calendar Google API-এর জন্য ক্লায়েন্ট লাইব্রেরি:

    gem install google-apis-drive_v3 google-apis-calendar_v3
  • Sinatra Ruby ওয়েব অ্যাপ্লিকেশন ফ্রেমওয়ার্ক।

    gem install sinatra

Node.js

এই ডকুমেন্টে Node.js কোড স্যাম্পেল রান করতে, আপনার এগুলি প্রয়োজন হবে:

  • Node.js-এর রক্ষণাবেক্ষণ LTS, অ্যাক্টিভ LTS বা বর্তমান রিলিজ।
  • Google APIs Node.js ক্লায়েন্ট:

    npm install googleapis crypto express express-session

HTTP/REST

OAuth 2.0 এন্ডপয়েন্ট সরাসরি কল করার জন্য আপনাকে কোনও লাইব্রেরি ইনস্টল করতে হবে না।

OAuth 2.0 অ্যাক্সেস টোকেন পাওয়া

ব্যবহারকারীর হয়ে API অনুরোধ করার জন্য ব্যবহারকারীর সম্মতি পেতে আপনার অ্যাপ্লিকেশন কীভাবে Google-এর OAuth 2.0 সার্ভারের সাথে ইন্টার‍্যাক্ট করে তা নিম্নলিখিত ধাপগুলি থেকে জানতে পারবেন। ব্যবহারকারীর অনুমোদন প্রয়োজন এমন Google API অনুরোধ কার্যকর করার আগে আপনার অ্যাপ্লিকেশনের কাছে অবশ্যই সেই সম্মতি থাকতে হবে।

নিম্নলিখিত তালিকাটি এই ধাপগুলির একটি সংক্ষিপ্তসার প্রদান করে:

  1. আপনার অ্যাপ্লিকেশনটি কোন কোন অনুমতি প্রয়োজন তা শনাক্ত করে।
  2. আপনার অ্যাপ্লিকেশন, অনুরোধ করা অনুমতির তালিকা সহ ব্যবহারকারীকে Google-এ রিডাইরেক্ট করে।
  3. ব্যবহারকারী আপনার অ্যাপ্লিকেশনকে অনুমতি দেবেন কিনা তা সিদ্ধান্ত নেন।
  4. ব্যবহারকারী কী সিদ্ধান্ত নিয়েছেন তা আপনার অ্যাপ্লিকেশন খুঁজে বের করে।
  5. ব্যবহারকারী অনুরোধ করা অনুমতি দিলে, আপনার অ্যাপ্লিকেশন এমন টোকেন পায় যা ব্যবহারকারীর হয়ে API অনুরোধ করার জন্য প্রয়োজন।

ধাপ ১: অনুমোদনের প্যারামিটার সেট করা

প্রথম ধাপ হল অনুমোদনের অনুরোধ তৈরি করা। সেই অনুরোধ এমন প্যারামিটার সেট করে যা আপনার অ্যাপ্লিকেশন শনাক্ত করে এবং ব্যবহারকারীকে আপনার অ্যাপ্লিকেশনকে যে অনুমতি দিতে বলা হবে তা নির্ধারণ করে।

  • আপনি OAuth 2.0 যাচাইকরণ ও অনুমোদনের জন্য Google ক্লায়েন্ট লাইব্রেরি ব্যবহার করলে, এইসব প্যারামিটারকে সংজ্ঞায়িত করে এমন একটি অবজেক্ট তৈরি ও কনফিগার করুন।
  • আপনি সরাসরি Google OAuth 2.0 এন্ডপয়েন্ট কল করলে, একটি URL জেনারেট করবেন এবং সেই URL-এ প্যারামিটার সেট করবেন।

নিম্নলিখিত ট্যাবগুলি ওয়েব সার্ভার অ্যাপ্লিকেশনের জন্য অনুমোদিত অনুমোদন প্যারামিটারগুলি সংজ্ঞায়িত করে। এছাড়াও, ভাষা-নির্দিষ্ট উদাহরণগুলি দেখায় যে কীভাবে একটি ক্লায়েন্ট লাইব্রেরি বা অনুমোদন লাইব্রেরি ব্যবহার করে একটি অবজেক্ট কনফিগার করতে হয় যা সেই প্যারামিটারগুলি সেট করে:

PHP

নিম্নলিখিত কোড স্নিপেট একটি Google\Client() অবজেক্ট তৈরি করে, যা অনুমোদনের অনুরোধে প্যারামিটারগুলি সংজ্ঞায়িত করে।

আপনার অ্যাপ্লিকেশন শনাক্ত করতে সেই অবজেক্ট আপনার client_secret.json ফাইল থেকে তথ্য ব্যবহার করে। (সেই ফাইল সম্পর্কে আরও জানতে অনুমোদনের ক্রেডেনশিয়াল তৈরি করা দেখুন।) এছাড়াও, অবজেক্টটি সেইসব স্কোপ শনাক্ত করে যেগুলির অ্যাক্সেস পাওয়ার জন্য আপনার অ্যাপ্লিকেশন অনুমতি চাইছে এবং আপনার অ্যাপ্লিকেশনের অথেন্টিকেশন এন্ডপয়েন্টের URL শনাক্ত করে, যা Google-এর OAuth 2.0 সার্ভার থেকে পাওয়া উত্তর ম্যানেজ করবে। শেষে, কোডটি ঐচ্ছিক access_type এবং include_granted_scopes প্যারামিটার সেট করে।

যেমন, এই কোডটি কোনও ব্যবহারকারীর Google Drive মেটাডেটা এবং ক্যালেন্ডার ইভেন্টে শুধু-পঠনযোগ্য, অফলাইন অ্যাক্সেসের অনুরোধ করে:

use Google\Client;

$client = new Client();

// Required, call the setAuthConfig function to load authorization credentials from
// client_secret.json file.
$client->setAuthConfig('client_secret.json');

// Required, to set the scope value, call the addScope function
$client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);

// Required, call the setRedirectUri function to specify a valid redirect URI for the
// provided client_id
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');

// Recommended, offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');

// Recommended, call the setState function. Using a state value can increase your assurance that
// an incoming connection is the result of an authentication request.
$client->setState($sample_passthrough_value);

// Optional, if your application knows which user is trying to authenticate, it can use this
// parameter to provide a hint to the Google Authentication Server.
$client->setLoginHint('hint@example.com');

// Optional, call the setPrompt function to set "consent" will prompt the user for consent
$client->setPrompt('consent');

// Optional, call the setIncludeGrantedScopes function with true to enable incremental
// authorization
$client->setIncludeGrantedScopes(true);

Python

নিম্নলিখিত কোড স্নিপেট অথরাইজেশন অনুরোধ তৈরি করতে google-auth-oauthlib.flow মডিউল ব্যবহার করে।

কোডটি একটি Flow অবজেক্ট তৈরি করে, যা client_secret.json ফাইল থেকে তথ্য ব্যবহার করে আপনার অ্যাপ্লিকেশন শনাক্ত করে। অনুমোদনের ক্রেডেনশিয়াল তৈরি করার পরে আপনি এই ফাইলটি ডাউনলোড করেছেন। এছাড়াও, সেই অবজেক্টটি আপনার অ্যাপ্লিকেশন অ্যাক্সেস করার অনুমতি চাইছে এমন স্কোপ এবং আপনার অ্যাপ্লিকেশনের auth এন্ডপয়েন্টের URL শনাক্ত করে, যা Google-এর OAuth 2.0 সার্ভার থেকে পাওয়া উত্তর ম্যানেজ করবে। শেষে, কোডটি ঐচ্ছিক access_type এবং include_granted_scopes প্যারামিটার সেট করে।

যেমন, এই কোডটি ব্যবহারকারীর Google Drive মেটাডেটা এবং Calendar ইভেন্টে শুধুমাত্র-পড়ার জন্য, অফলাইন অ্যাক্সেসের অনুরোধ করে:

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Required, call the from_client_secrets_file method to retrieve the client ID from a
# client_secret.json file. The client ID (from that file) and access scopes are required. (You can
# also use the from_client_config method, which passes the client configuration as it originally
# appeared in a client secrets file but doesn't access the file itself.)
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file('client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly',
            'https://www.googleapis.com/auth/calendar.readonly'])

# Required, indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
flow.redirect_uri = 'https://www.example.com/oauth2callback'

# Generate URL for request to Google's OAuth 2.0 server.
# Use kwargs to set optional request parameters.
authorization_url, state = flow.authorization_url(
    # Recommended, enable offline access so that you can refresh an access token without
    # re-prompting the user for permission. Recommended for web server apps.
    access_type='offline',
    # Optional, enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true',
    # Optional, if your application knows which user is trying to authenticate, it can use this
    # parameter to provide a hint to the Google Authentication Server.
    login_hint='hint@example.com',
    # Optional, set prompt to 'consent' will prompt the user for consent
    prompt='consent')

Ruby

আপনার অ্যাপ্লিকেশনে ক্লায়েন্ট অবজেক্ট কনফিগার করার জন্য আপনার তৈরি করা client_secrets.json ফাইলটি ব্যবহার করুন। আপনি যখন কোনও ক্লায়েন্ট অবজেক্ট কনফিগার করেন, তখন আপনার অ্যাপ্লিকেশনকে যে স্কোপগুলি অ্যাক্সেস করতে হবে তা নির্দিষ্ট করেন, সাথে আপনার অ্যাপ্লিকেশনের প্রমাণীকরণ এন্ডপয়েন্টের URL, যা OAuth 2.0 সার্ভার থেকে আসা উত্তর ম্যানেজ করবে।

যেমন, এই কোডটি ব্যবহারকারীর Google Drive মেটাডেটা এবং Calendar ইভেন্টে শুধুমাত্র-পড়ার জন্য, অফলাইন অ্যাক্সেসের অনুরোধ করে:

require 'googleauth'
require 'googleauth/web_user_authorizer'
require 'googleauth/stores/redis_token_store'

require 'google/apis/drive_v3'
require 'google/apis/calendar_v3'

# Required, call the from_file method to retrieve the client ID from a
# client_secret.json file.
client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')

# Required, scope value 
# Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
         'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']

# Required, Authorizers require a storage instance to manage long term persistence of
# access and refresh tokens.
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)

# Required, indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
callback_uri = '/oauth2callback'

# To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
# from the client_secret.json file. To get these credentials for your application, visit
# https://console.cloud.google.com/apis/credentials.
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope,
                                                token_store, callback_uri)

আপনার অ্যাপ্লিকেশন OAuth 2.0 অপারেশন পারফর্ম করার জন্য ক্লায়েন্ট অবজেক্ট ব্যবহার করে, যেমন অনুমোদন অনুরোধ URL তৈরি করা এবং HTTP অনুরোধে অ্যাক্সেস টোকেন প্রয়োগ করা।

Node.js

নিম্নলিখিত কোড স্নিপেট একটি google.auth.OAuth2 অবজেক্ট তৈরি করে, যা অনুমোদনের অনুরোধে প্যারামিটারগুলি সংজ্ঞায়িত করে।

আপনার অ্যাপ্লিকেশন শনাক্ত করতে সেই অবজেক্ট client_secret.json ফাইল থেকে তথ্য ব্যবহার করে। অ্যাক্সেস টোকেন ফিরিয়ে আনার জন্য ব্যবহারকারীর থেকে অনুমতি চাইতে, আপনি তাকে সম্মতি পৃষ্ঠায় রিডাইরেক্ট করেন। সম্মতি পৃষ্ঠার URL তৈরি করতে:

const {google} = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
 * from the client_secret.json file. To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a secure random state value.
const state = crypto.randomBytes(32).toString('hex');

// Store state in the session
req.session.state = state;

// Generate a url that asks permissions for the Drive activity and Google Calendar scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true,
  // Include the state parameter to reduce the risk of CSRF attacks.
  state: state
});

গুরুত্বপূর্ণ - refresh_token শুধুমাত্র প্রথম অনুমোদনের ক্ষেত্রে ফেরত দেওয়া হয়। আরও বিবরণ এখানে।

HTTP/REST

Google-এর OAuth 2.0 এন্ডপয়েন্ট https://accounts.google.com/o/oauth2/v2/auth-এ আছে। এই এন্ডপয়েন্ট শুধুমাত্র HTTPS-এর মাধ্যমে অ্যাক্সেস করা যায়। প্লেন HTTP কানেকশন প্রত্যাখ্যান করা হয়েছে।

Google-এর অনুমোদন সার্ভার ওয়েব সার্ভার অ্যাপ্লিকেশনের জন্য নিম্নলিখিত কোয়েরি স্ট্রিং প্যারামিটার সমর্থন করে:

প্যারামিটারগুলি
client_id আবশ্যক

আপনার অ্যাপ্লিকেশনের ক্লায়েন্ট আইডি। আপনি এই ভ্যালু Cloud Console ক্লায়েন্ট পৃষ্ঠা থেকে দেখতে পাবেন।

redirect_uri আবশ্যক

ব্যবহারকারী অথরাইজেশন ফ্লো সম্পূর্ণ করার পরে API সার্ভার ব্যবহারকারীকে কোথায় রিডাইরেক্ট করবে তা নির্ধারণ করে। OAuth 2.0 ক্লায়েন্টের জন্য অনুমোদিত রিডাইরেক্ট URI-এর মধ্যে কোনও একটির সাথে ভ্যালু হুবহু মিলতে হবে, যা আপনি ক্লায়েন্টের Cloud Console ক্লায়েন্ট পৃষ্ঠা-তে কনফিগার করেছেন। এই ভ্যালু যদি প্রদত্ত client_id-এর জন্য অনুমোদিত রিডাইরেক্ট URI-এর সাথে ম্যাচ না করে, তাহলে আপনি redirect_uri_mismatch সমস্যা দেখতে পাবেন।

মনে রাখবেন, http বা https স্কিম, কেস ও ট্রেলিং স্ল্যাশ ('/') সবকটিই ম্যাচ করতে হবে।

response_type আবশ্যক

Google OAuth 2.0 এন্ডপয়েন্ট কোনও অনুমোদন কোড রিটার্ন করে কিনা তা নির্ধারণ করে।

ওয়েব সার্ভার অ্যাপ্লিকেশনের জন্য প্যারামিটার ভ্যালু code হিসেবে সেট করুন।

scope আবশ্যক

একটি স্পেস-ডিলিমিটেড স্কোপের তালিকা যা সেইসব রিসোর্সকে শনাক্ত করে যেগুলি আপনার অ্যাপ্লিকেশন ব্যবহারকারীর হয়ে অ্যাক্সেস করতে পারে। এইসব ভ্যালু সম্মতি স্ক্রিনকে জানায় যে Google ব্যবহারকারীকে কী দেখাবে।

স্কোপ আপনার অ্যাপ্লিকেশনকে শুধুমাত্র প্রয়োজনীয় রিসোর্স অ্যাক্সেস করার অনুরোধ করতে দেয় এবং ব্যবহারকারীদের আপনার অ্যাপ্লিকেশনকে দেওয়া অ্যাক্সেসের পরিমাণ নিয়ন্ত্রণ করতে দেয়। তাই, অনুরোধ করা স্কোপের সংখ্যা এবং ব্যবহারকারীর সম্মতি পাওয়ার সম্ভাবনার মধ্যে বিপরীত সম্পর্ক রয়েছে।

আমরা সাজেস্ট করি যে আপনার অ্যাপ্লিকেশন যখনই সম্ভব হবে তখনই প্রসঙ্গে অনুমোদনের স্কোপে অ্যাক্সেসের অনুরোধ করবে। ইনক্রিমেন্টাল অনুমোদন ব্যবহার করে, প্রাসঙ্গিকতার সাথে ব্যবহারকারীর ডেটা অ্যাক্সেস করার অনুরোধ করে, আপনি ব্যবহারকারীদের বুঝতে সাহায্য করেন যে আপনার অ্যাপ্লিকেশন কেন সেই অ্যাক্সেস চাইছে।

access_type সাজেস্ট করা হয়

ব্যবহারকারী ব্রাউজারে উপস্থিত না থাকলে আপনার অ্যাপ্লিকেশন অ্যাক্সেস টোকেন রিফ্রেশ করতে পারবে কিনা তা নির্দেশ করে। প্যারামিটারের সঠিক ভ্যালু হল online, যা ডিফল্ট ভ্যালু এবং offline।

ব্যবহারকারী ব্রাউজারে না থাকলে, আপনার অ্যাপ্লিকেশনকে অ্যাক্সেস টোকেন রিফ্রেশ করতে হলে, ভ্যালু offline হিসেবে সেট করুন । এই ডকুমেন্টে পরে অ্যাক্সেস টোকেন রিফ্রেশ করার পদ্ধতি বর্ণনা করা হয়েছে। এই ভ্যালু Google যাচাইকরণ সার্ভারকে নির্দেশ দেয় যে আপনার অ্যাপ্লিকেশন প্রথমবার টোকেনের জন্য যাচাইকরণ কোড এক্সচেঞ্জ করলে একটি রিফ্রেশ টোকেন ও একটি অ্যাক্সেস টোকেন ফেরত দিতে হবে।

state সাজেস্ট করা হয়

আপনার অ্যাপ্লিকেশন, আপনার অনুমতি সংক্রান্ত অনুরোধ এবং অনুমতি সার্ভারের উত্তরের মধ্যে স্টেট বজায় রাখার জন্য ব্যবহার করে এমন যেকোনও স্ট্রিং ভ্যালু নির্দিষ্ট করে। ব্যবহারকারী আপনার অ্যাপ্লিকেশনের অ্যাক্সেসের অনুরোধে সম্মতি দিলে বা তা প্রত্যাখ্যান করলে, সার্ভারটি ঠিক সেই মানটি ফেরত দেয় যা আপনি redirect_uri-এর URL কোয়েরি কম্পোনেন্টে (?) name=value পেয়ার হিসেবে পাঠান।

আপনি এই প্যারামিটারটি বিভিন্ন উদ্দেশ্যে ব্যবহার করতে পারেন, যেমন ব্যবহারকারীকে আপনার অ্যাপ্লিকেশনের সঠিক রিসোর্সে নির্দেশ করা, ননস পাঠানো এবং ক্রস-সাইট অনুরোধ জালিয়াতি কমানো। আপনার redirect_uri অনুমান করা যেতে পারে, তাই state ভ্যালু ব্যবহার করলে, ইনকামিং কানেকশন যে একটি যাচাইকরণ অনুরোধের ফলাফল, সেই ব্যাপারে আপনার নিশ্চয়তা বাড়তে পারে। আপনি যদি কোনও র‍্যান্ডম স্ট্রিং তৈরি করেন বা কোনও কুকির হ্যাশ এনকোড করেন অথবা অন্য কোনও ভ্যালু যা ক্লায়েন্টের স্ট্যাটাস ক্যাপচার করে, তাহলে আপনি অনুরোধ এবং উত্তর একই ব্রাউজার থেকে এসেছে কিনা তা অতিরিক্তভাবে নিশ্চিত করতে উত্তরটি যাচাই করতে পারেন, ক্রস-সাইট অনুরোধ জালিয়াতি-এর মতো আক্রমণ থেকে সুরক্ষা প্রদান করে। state টোকেন কীভাবে তৈরি ও কনফার্ম করতে হয় তার উদাহরণ দেখতে OpenID Connect ডকুমেন্টেশন দেখুন।

include_granted_scopes ঐচ্ছিক

অ্যাপ্লিকেশনকে ইনক্রিমেন্টাল অথরাইজেশন ব্যবহার করার অনুমতি দেয় যাতে কন্টেক্সটে অতিরিক্ত স্কোপ অ্যাক্সেস করার অনুরোধ করা যায়। আপনি এই প্যারামিটারের ভ্যালু true হিসেবে সেট করলে এবং অনুমোদনের অনুরোধ মঞ্জুর করা হলে, নতুন অ্যাক্সেস টোকেন এমন যেকোনও স্কোপ কভার করবে যেখানে ব্যবহারকারী আগে অ্যাপ্লিকেশন অ্যাক্সেস করার অনুমতি দিয়েছেন। উদাহরণ দেখতে ইনক্রিমেন্টাল অথরাইজেশন বিভাগ দেখুন।

login_hint ঐচ্ছিক

কোন ব্যবহারকারী যাচাই করার চেষ্টা করছেন তা আপনার অ্যাপ্লিকেশন জানলে, এটি Google যাচাইকরণ সার্ভারকে ইঙ্গিত দিতে এই প্যারামিটার ব্যবহার করতে পারে। সাইন-ইন ফর্মে ইমেল ফিল্ড আগে থেকে পূরণ করে অথবা উপযুক্ত মাল্টি-লগ-ইন সেশন বেছে নিয়ে লগ-ইন ফ্লো সহজ করার জন্য সার্ভার এই ইঙ্গিত ব্যবহার করে।

প্যারামিটারের মান কোনও ইমেল আইডি বা sub আইডেন্টিফায়ারে সেট করুন, যা ব্যবহারকারীর Google আইডির সমতুল্য।

prompt ঐচ্ছিক

ব্যবহারকারীকে দেখানোর জন্য স্পেস-ডিলিমিটেড, ছোট ও বড় হাতের অক্ষরের মধ্যে পার্থক্য করা হয় এমন প্রম্পটের তালিকা। আপনি এই প্যারামিটার উল্লেখ না করলে, আপনার প্রজেক্ট অ্যাক্সেস করার অনুরোধ করলে ব্যবহারকারীকে শুধুমাত্র প্রথমবারই প্রম্পট করা হবে। আরও তথ্যের জন্য আবার সম্মতি দেওয়ার জন্য প্রম্পট করা দেখুন।

সম্ভাব্য ভ্যালুগুলি হল:

none কোনও যাচাইকরণ বা সম্মতি সংক্রান্ত স্ক্রিন দেখাবেন না। অন্যান্য মানের সাথে উল্লেখ করা যাবে না।
consent সম্মতির জন্য ব্যবহারকারীকে প্রম্পট করুন।
select_account ব্যবহারকারীকে একটি অ্যাকাউন্ট বেছে নিতে প্রম্পট করুন।

ধাপ ২: Google-এর OAuth 2.0 সার্ভারে রিডাইরেক্ট করা

যাচাইকরণ ও অনুমোদন প্রক্রিয়া শুরু করতে ব্যবহারকারীকে Google-এর OAuth 2.0 সার্ভারে রিডাইরেক্ট করুন। সাধারণত, আপনার অ্যাপ্লিকেশনকে প্রথমবার ব্যবহারকারীর ডেটা অ্যাক্সেস করতে হলে এটি ঘটে। ইনক্রিমেন্টাল অনুমোদনের ক্ষেত্রে, আপনার অ্যাপ্লিকেশন যখন প্রথমবার অতিরিক্ত রিসোর্স অ্যাক্সেস করতে চায়, তখনও এই ধাপটি ঘটে। এই রিসোর্স অ্যাক্সেস করার অনুমতি অ্যাপ্লিকেশনের কাছে থাকে না।

PHP

  1. Google-এর OAuth 2.0 সার্ভার থেকে অ্যাক্সেস অনুরোধ করার জন্য একটি URL তৈরি করুন:
    $auth_url = $client->createAuthUrl();
  2. ব্যবহারকারীকে $auth_url-এ রিডাইরেক্ট করুন:
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Python

এই উদাহরণে দেখানো হয়েছে যে Flask ওয়েব অ্যাপ্লিকেশন ফ্রেমওয়ার্ক ব্যবহার করে কীভাবে ব্যবহারকারীকে অথরাইজেশন URL-এ রিডাইরেক্ট করতে হয়:

return flask.redirect(authorization_url)

Ruby

  1. Google-এর OAuth 2.0 সার্ভার থেকে অ্যাক্সেসের অনুরোধ করার জন্য একটি URL তৈরি করুন:
    auth_uri = authorizer.get_authorization_url(request: request)
  2. ব্যবহারকারীকে auth_uri-এ রিডাইরেক্ট করুন।

Node.js

  1. Google-এর OAuth 2.0 সার্ভার থেকে অ্যাক্সেস পেতে, ধাপ ১-এ generateAuthUrl পদ্ধতিতে তৈরি করা URL authorizationUrl ব্যবহার করুন।
  2. ব্যবহারকারীকে authorizationUrl-এ রিডাইরেক্ট করুন।
    res.redirect(authorizationUrl);

HTTP/REST

Google-এর অনুমোদন সার্ভারে রিডাইরেক্ট করার নমুনা

নিচে একটি URL-এর উদাহরণ দেখানো হয়েছে, যাতে লাইন ব্রেক ও স্পেস দেওয়া আছে যাতে পড়তে সুবিধা হয়।

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//developers.google.com/oauthplayground&
 client_id=client_id

অনুরোধ URL তৈরি করার পরে, ব্যবহারকারীকে সেটিতে রিডাইরেক্ট করুন।

Google-এর OAuth 2.0 সার্ভার ব্যবহারকারীকে যাচাই করে এবং অনুরোধ করা স্কোপ অ্যাক্সেস করার জন্য আপনার অ্যাপ্লিকেশনের জন্য ব্যবহারকারীর থেকে সম্মতি নেয়। আপনার উল্লেখ করা রিডাইরেক্ট URL ব্যবহার করে আপনার অ্যাপ্লিকেশনে উত্তর পাঠানো হয়।

ধাপ ৩: Google ব্যবহারকারীকে সম্মতি দেওয়ার জন্য প্রম্পট করে

এই ধাপে, ব্যবহারকারী সিদ্ধান্ত নেন যে আপনার অ্যাপ্লিকেশনকে অনুরোধ করা অ্যাক্সেস দেবেন কিনা। এই পর্যায়ে, Google একটি সম্মতি উইন্ডো দেখায় যেখানে আপনার অ্যাপ্লিকেশনের নাম এবং Google API পরিষেবা দেখানো হয়, যেটির জন্য ব্যবহারকারীর অনুমোদনের ক্রেডেনশিয়াল সহ অ্যাক্সেস করার অনুমতি চাওয়া হচ্ছে এবং যে অ্যাক্সেসের স্কোপ মঞ্জুর করা হবে তার সারসংক্ষেপ দেখানো হয়। ব্যবহারকারী তখন আপনার অ্যাপ্লিকেশনের অনুরোধ করা এক বা একাধিক স্কোপে অ্যাক্সেস দেওয়ার জন্য সম্মতি দিতে পারেন বা অনুরোধ প্রত্যাখ্যান করতে পারেন।

এই পর্যায়ে আপনার অ্যাপ্লিকেশনকে কিছু করতে হবে না কারণ এটি Google-এর OAuth 2.0 সার্ভার থেকে উত্তরের জন্য অপেক্ষা করে যা থেকে বোঝা যায় যে কোনও অ্যাক্সেস দেওয়া হয়েছে কিনা। সেই উত্তরটি নিম্নলিখিত ধাপে ব্যাখ্যা করা হয়েছে।

সমস্যা

Google-এর OAuth 2.0 অনুমোদন এন্ডপয়েন্টে করা অনুরোধে প্রত্যাশিত যাচাইকরণ ও অনুমোদন ফ্লোয়ের পরিবর্তে ব্যবহারকারী-কেন্দ্রিক সমস্যার মেসেজ দেখানো হতে পারে। সাধারণ সমস্যার কোড ও সাজেস্ট করা সমাধান হল:

admin_policy_enforced

Google Workspace অ্যাডমিনিস্ট্রেটরের নীতির কারণে, Google অ্যাকাউন্ট অনুরোধ করা এক বা একাধিক স্কোপ অনুমোদন করতে পারছে না। Google Workspace অ্যাডমিন সহায়তা নিবন্ধ দেখুন কোন থার্ড-পার্টি ও ইন্টার্নাল অ্যাপ Google Workspace ডেটা অ্যাক্সেস করবে তা নিয়ন্ত্রণ করুন অ্যাডমিনিস্ট্রেটর কীভাবে আপনার OAuth ক্লায়েন্ট আইডিকে স্পষ্টভাবে অ্যাক্সেস না দেওয়া পর্যন্ত সমস্ত স্কোপ বা সংবেদনশীল ও বিধিনিষেধযুক্ত স্কোপে অ্যাক্সেস সীমাবদ্ধ করতে পারেন সেই সম্পর্কে আরও তথ্য পেতে।

disallowed_useragent

Google-এর OAuth 2.0 নীতি অনুযায়ী অনুমোদিত নয় এমন একটি এম্বেড করা ইউজার-এজেন্টের মধ্যে অনুমোদনের এন্ডপয়েন্ট দেখানো হয়।

iOS এবং macOS ডেভেলপাররা WKWebView-এ অনুমোদনের অনুরোধ খোলার সময় এই সমস্যার সম্মুখীন হতে পারেন। এর পরিবর্তে, ডেভেলপারদের iOS লাইব্রেরি ব্যবহার করা উচিত, যেমন iOS-এর জন্য Google সাইন-ইন বা OpenID Foundation-এর iOS-এর জন্য AppAuth।

iOS বা macOS অ্যাপ এম্বেড করা ইউজার-এজেন্টে সাধারণ ওয়েব লিঙ্ক খুললে এবং ব্যবহারকারী আপনার সাইট থেকে Google-এর OAuth 2.0 অনুমোদন এন্ডপয়েন্টে নেভিগেট করলে ওয়েব ডেভেলপাররা এই সমস্যার সম্মুখীন হতে পারেন। ডেভেলপারদের উচিত অপারেটিং সিস্টেমের ডিফল্ট লিঙ্ক হ্যান্ডলারে সাধারণ লিঙ্ক খোলার অনুমতি দেওয়া, যার মধ্যে ইউনিভার্সাল লিঙ্ক হ্যান্ডলার বা ডিফল্ট ব্রাউজার অ্যাপ, দুটিই অন্তর্ভুক্ত। SFSafariViewController লাইব্রেরিও একটি কাজ করে এমন বিকল্প।

org_internal

অনুরোধে থাকা OAuth ক্লায়েন্ট আইডি এমন একটি প্রোজেক্টের অংশ যা নির্দিষ্ট Google Cloud সংস্থার Google অ্যাকাউন্টে অ্যাক্সেস সীমিত করে। এই কনফিগারেশন বিকল্প সম্পর্কে আরও তথ্যের জন্য, আপনার OAuth সম্মতি স্ক্রিন সেট-আপ করা সংক্রান্ত সহায়তা নিবন্ধের ব্যবহারকারীর ধরন বিভাগটি দেখুন।

invalid_client

OAuth ক্লায়েন্ট সিক্রেট সঠিক নয়। এই অনুরোধের জন্য ব্যবহৃত ক্লায়েন্ট আইডি ও সিক্রেট সহ OAuth ক্লায়েন্ট কনফিগারেশন পর্যালোচনা করুন।

deleted_client

অনুরোধ করার জন্য যে OAuth ক্লায়েন্ট ব্যবহার করা হচ্ছে সেটি মুছে দেওয়া হয়েছে। ম্যানুয়ালি বা অটোমেটিক মুছে ফেলা হতে পারে যদি ক্লায়েন্ট ব্যবহার না করা হয় । মুছে ফেলা ক্লায়েন্টকে ৩০ দিনের মধ্যে ফিরিয়ে আনা যাবে। আরও জানুন ।

invalid_grant

অ্যাক্সেস টোকেন রিফ্রেশ করার সময় অথবা ইনক্রিমেন্টাল অনুমোদন ব্যবহার করার সময়, টোকেনের মেয়াদ শেষ হয়ে যেতে পারে অথবা সেটি বাতিল হয়ে যেতে পারে। ব্যবহারকারীকে আবার যাচাই করুন এবং নতুন টোকেন পাওয়ার জন্য ব্যবহারকারীর সম্মতি চান। আপনি যদি এই সমস্যাটি দেখতে পেতে থাকেন, তাহলে আপনার অ্যাপ্লিকেশন সঠিকভাবে কনফিগার করা হয়েছে কিনা এবং আপনি আপনার অনুরোধে সঠিক টোকেন ও প্যারামিটার ব্যবহার করছেন কিনা তা নিশ্চিত করুন। অন্যথায়, ব্যবহারকারীর অ্যাকাউন্ট মুছে দেওয়া বা বন্ধ করে দেওয়া হতে পারে।

redirect_uri_mismatch

অনুমোদনের অনুরোধে পাস করা redirect_uri OAuth ক্লায়েন্ট আইডির জন্য অনুমোদিত রিডাইরেক্ট URI-এর সাথে মিলছে না। Google Cloud Console-এর ক্লায়েন্ট পৃষ্ঠা থেকে অনুমোদিত রিডাইরেক্ট URI পর্যালোচনা করুন।

redirect_uri প্যারামিটারটি OAuth আউট-অফ-ব্যান্ড (OOB) ফ্লোকে রেফার করতে পারে যা বন্ধ করে দেওয়া হয়েছে এবং আর কাজ করে না। আপনার ইন্টিগ্রেশন আপডেট করতে মাইগ্রেশন গাইড দেখুন।

invalid_request

আপনার করা অনুরোধে কোনও সমস্যা হয়েছে। একাধিক কারণে এটি হতে পারে:

  • অনুরোধটি সঠিকভাবে ফর্ম্যাট করা হয়নি
  • অনুরোধে প্রয়োজনীয় প্যারামিটার নেই
  • অনুরোধটি এমন একটি যাচাইকরণ পদ্ধতি ব্যবহার করে যা Google-এ কাজ করে না। আপনার OAuth ইন্টিগ্রেশন সাজেস্ট করা ইন্টিগ্রেশন পদ্ধতি ব্যবহার করছে কিনা তা যাচাই করুন

ধাপ ৪: OAuth 2.0 সার্ভার রেসপন্স ম্যানেজ করা

OAuth 2.0 সার্ভার, অনুরোধে উল্লেখ করা URL ব্যবহার করে আপনার অ্যাপ্লিকেশনের অ্যাক্সেসের অনুরোধের উত্তর দেয়।

ব্যবহারকারী অ্যাক্সেসের অনুরোধ অনুমোদন করলে, উত্তরে একটি অনুমোদন কোড থাকে। ব্যবহারকারী অনুরোধ অনুমোদন না করলে, উত্তরে একটি সমস্যার মেসেজ থাকে। ওয়েব সার্ভারে ফেরত আসা অথরাইজেশন কোড বা সমস্যার মেসেজ কোয়েরি স্ট্রিংয়ে দেখা যায়, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

একটি ত্রুটি প্রতিক্রিয়া:

https://oauth2.example.com/auth?error=access_denied

অনুমোদন কোড সংক্রান্ত উত্তর:

https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7

OAuth 2.0 সার্ভার রেসপন্সের নমুনা

আপনি নিম্নলিখিত স্যাম্পেল URL-এ ক্লিক করে এই ফ্লো পরীক্ষা করতে পারেন, যা আপনার Google Drive-এ ফাইলের মেটাডেটা দেখার জন্য শুধুমাত্র পড়ার অ্যাক্সেস এবং আপনার Google Calendar ইভেন্ট দেখার জন্য শুধুমাত্র পড়ার অ্যাক্সেসের অনুরোধ করে:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//developers.google.com/oauthplayground&
 client_id=client_id

OAuth 2.0 ফ্লো সম্পূর্ণ করার পরে, আপনার ব্রাউজার আপনাকে OAuth 2.0 প্লেগ্রাউন্ডে রিডাইরেক্ট করে, এটি OAuth ফ্লো পরীক্ষা করার একটি টুল। আপনি দেখতে পাবেন যে OAuth 2.0 Playground অটোমেটিক অনুমোদন কোড ক্যাপচার করেছে।

ধাপ ৫: রিফ্রেশ ও অ্যাক্সেস টোকেনের জন্য অথরাইজেশন কোড এক্সচেঞ্জ করুন

ওয়েব সার্ভার অনুমোদন কোড পাওয়ার পরে, এটি অ্যাক্সেস টোকেনের জন্য অনুমোদন কোড বিনিময় করতে পারে।

PHP

অ্যাক্সেস টোকেনের জন্য অথরাইজেশন কোড এক্সচেঞ্জ করতে, fetchAccessTokenWithAuthCode পদ্ধতি ব্যবহার করুন:

$access_token = $client->fetchAccessTokenWithAuthCode($_GET['code']);

Python

আপনার কলব্যাক পৃষ্ঠায়, অনুমোদনের সার্ভার উত্তর যাচাই করতে google-auth লাইব্রেরি ব্যবহার করুন। তারপরে, অ্যাক্সেস টোকেনের জন্য সেই উত্তরে থাকা অনুমোদন কোডটি এক্সচেঞ্জ করতে flow.fetch_token পদ্ধতি ব্যবহার করুন:

state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'],
    state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)

# Store the credentials in browser session storage, but for security: client_id, client_secret,
# and token_uri are instead stored only on the backend server.
credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'granted_scopes': credentials.granted_scopes}

Ruby

আপনার কলব্যাক পৃষ্ঠায়, অনুমোদনের সার্ভারের উত্তর যাচাই করতে googleauth লাইব্রেরি ব্যবহার করুন। authorizer.handle_auth_callback_deferred পদ্ধতি ব্যবহার করে অথরাইজেশন কোড সেভ করুন এবং যে URL থেকে অথরাইজেশনের অনুরোধ করা হয়েছিল সেখানে রিডাইরেক্ট করুন। এটি ব্যবহারকারীর সেশনে ফলাফল সাময়িকভাবে স্ট্যাশ করে কোড এক্সচেঞ্জ পিছিয়ে দেয়।

  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url

Node.js

অ্যাক্সেস টোকেনের জন্য অথরাইজেশন কোড এক্সচেঞ্জ করতে, getToken মেথড ব্যবহার করুন:

const url = require('url');

// Receive the callback from Google's OAuth 2.0 server.
app.get('/oauth2callback', async (req, res) => {
  let q = url.parse(req.url, true).query;

  if (q.error) { // An error response e.g. error=access_denied
    console.log('Error:' + q.error);
  } else if (q.state !== req.session.state) { //check state value
    console.log('State mismatch. Possible CSRF attack');
    res.end('State mismatch. Possible CSRF attack');
  } else { // Get access and refresh tokens (if access_type is offline)

    let { tokens } = await oauth2Client.getToken(q.code);
    oauth2Client.setCredentials(tokens);
});

HTTP/REST

অ্যাক্সেস টোকেনের জন্য যাচাইকরণ কোড পেতে, https://oauth2.googleapis.com/token এন্ডপয়েন্ট কল করুন এবং নিম্নলিখিত প্যারামিটার সেট করুন:

ফিল্ড
client_id Cloud Console থেকে পাওয়া ক্লায়েন্ট আইডি ক্লায়েন্ট পৃষ্ঠা।
client_secret ঐচ্ছিক

Cloud Console থেকে পাওয়া ক্লায়েন্ট সিক্রেট ক্লায়েন্ট পৃষ্ঠা।

code প্রাথমিক অনুরোধ থেকে প্রাপ্ত অনুমোদনের কোড।
grant_type OAuth 2.0 স্পেসিফিকেশনে যেমন উল্লেখ করা আছে, এই ফিল্ডের ভ্যালু অবশ্যই authorization_code হিসেবে সেট করতে হবে।
redirect_uri আপনার প্রোজেক্টের জন্য তালিকাভুক্ত রিডাইরেক্ট URI-এর মধ্যে একটি হল প্রদত্ত client_id-এর জন্য Cloud Console-এর ক্লায়েন্ট পৃষ্ঠা।

DPoP ব্যবহার করা ঐচ্ছিক হলেও, আরও বেশি নিরাপত্তার জন্য এটি ব্যবহার করার সাজেশন দেওয়া হয়। DPoP-এর নিরাপত্তা ব্যক্তিগত কী একটি ডিভাইসে সীমাবদ্ধ থাকার উপর নির্ভর করে; আমরা এটি এমনভাবে সেভ করার সুপারিশ করি যাতে এটি ডিভাইসের বাইরে কপি করা না যায়, যেমন TPM, Secure Enclaves বা অন্যান্য হার্ডওয়্যার-ব্যাকড কীস্টোর ব্যবহার করে। DPoP ব্যবহার করতে, আপনার অ্যাপ্লিকেশনকে টোকেন এন্ডপয়েন্টে প্রতিটি অনুরোধের জন্য একটি নতুন, অনন্য DPoP প্রমাণ JWT তৈরি করতে হবে এবং এটি একটি HTTP অনুরোধ হেডার হিসাবে যোগ করতে হবে।

শিরোনাম প্রয়োজনীয় বিবরণ
DPoP ঐচ্ছিক DPoP প্রমাণ হল একটি JWT যা প্রাইভেট কীয়ের মালিকানা প্রমাণ করে। এটি একটি হেডার, প্যারামিটার নয়। প্রদান করা হলে, ফেরত আসা টোকেন এই 'কী'-এর সাথে বাউন্ড করা হয়। প্রতিটি অনুরোধের জন্য একটি নতুন, অনন্য প্রমাণ তৈরি করতে হবে এবং এতে অবশ্যই htm (HTTP পদ্ধতি) এবং htu (HTTP URI) দাবি অন্তর্ভুক্ত থাকতে হবে যা অনুরোধের সাথে মেলে।

নিম্নলিখিত স্নিপেট একটি নমুনা অনুরোধ দেখায়:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\
 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
redirect_uri=https%3A//developers.google.com/oauthplayground&
grant_type=authorization_code

DPoP প্রমাণ তৈরি করা

কমান্ড লাইন থেকে OpenSSL ব্যবহার করে কীভাবে DPoP প্রমাণ তৈরি করতে হয় তা নিম্নলিখিত ধাপগুলি থেকে জানুন:

  1. EC P-256 কী পেয়ার জেনারেট করুন:
    openssl ecparam -name prime256v1 -genkey -noout -out dpop_private.pem
    openssl ec -in dpop_private.pem -pubout -out dpop_public.pem
  2. DPoP হেডার তৈরি করুন:

    হেডারে অবশ্যই typ, alg এবং jwk (সর্বজনীন কী) দাবি অন্তর্ভুক্ত করতে হবে। x এবং y মান হল আপনার EC সর্বজনীন কী-এর Base64Url-এনকোড করা কোঅর্ডিনেট। এই JSON-কে Base64Url এনকোড করুন:

    {
      "typ":"dpop+jwt",
      "alg":"ES256",
      "jwk": {
        "kty":"EC",
        "x":"YOUR_PUBLIC_KEY_X",
        "y":"YOUR_PUBLIC_KEY_Y",
        "crv":"P-256"
      }
    }
  3. DPoP পে-লোড তৈরি করুন:

    পে-লোডে অবশ্যই jti (অনুরোধের জন্য একটি অনন্য শনাক্তকারী), htm (HTTP পদ্ধতি, যেমন, POST), htu (HTTP URI, যেমন, https://oauth2.googleapis.com/token), এবং iat (ইস্যু করার সময়) অন্তর্ভুক্ত থাকতে হবে। আগের অনুরোধের উত্তরে DPoP-Nonce হেডারে সার্ভার থেকে ননস পেয়ে থাকলে, আপনাকে অবশ্যই nonce দাবিতে সেই ননস ভ্যালু অন্তর্ভুক্ত করতে হবে। অনুমোদন কোড এক্সচেঞ্জের জন্য ননস দাবি ঐচ্ছিক এবং DPoP-Nonce হেডার আগে পাওয়া গেলে তবেই এটি ব্যবহার করা হয়। এই JSON-কে Base64Url এনকোড করুন:

    {
      "jti":"JTI_VALUE",
      "htm":"POST",
      "htu":"https://oauth2.googleapis.com/token",
      "iat":YOUR_JWT_ISSUED_TIME,
      "nonce":"SERVER_PROVIDED_NONCE"
    }

    jti ভ্যালু এক্সচেঞ্জের ধরনের উপর নির্ভর করে:

    • অনুমোদন কোড এক্সচেঞ্জের ক্ষেত্রে, jti অবশ্যই অনুমোদন কোডের Base64Url-এনকোড করা SHA256 হ্যাশ হতে হবে: "jti":"BASE64URL(SHA256(AUTHORIZATION_CODE))".
    • রিফ্রেশ টোকেন এক্সচেঞ্জের জন্য, jti অবশ্যই একটি অনন্য প্রতি-অনুরোধ শনাক্তকারী হতে হবে: "jti":"YOUR_UNIQUE_PER_REQUEST_IDENTIFIER".
  4. প্রমাণে স্বাক্ষর করুন:

    এনকোড করা হেডার ও পেলোডকে একটি পিরিয়ড (.) দিয়ে কনক্যাটিনেট করুন, তারপর ES256 ব্যবহার করে আপনার ব্যক্তিগত কী দিয়ে ফলাফলটি সাইন করুন। মনে রাখবেন যে JWS-এর ক্ষেত্রে স্বাক্ষরটি র R | S কনক্যাটিনেটেড ফর্ম্যাটে (P-256-এর জন্য ৬৪ বাইট) হতে হবে। সরাসরি OpenSSL ব্যবহার করলে, আপনাকে অবশ্যই ডিফল্ট ASN.1 DER-এনকোডেড সিগনেচারকে এই র ফর্ম্যাটে কনভার্ট করতে হবে।

টোকেন সহ উত্তর পেলে বুঝতে হবে যে সফলভাবে এক্সচেঞ্জ করা গেছে। 200 OK এক্সচেঞ্জের সময় সঠিক DPoP প্রমাণ ব্যবহার করা হলে, Google যে রিফ্রেশ টোকেন ফেরত দেয় সেটি আপনার 'কী'-এর সাথে DPoP-বাউন্ড হবে, কিন্তু অ্যাক্সেস টোকেন DPoP-বাউন্ড হবে না। অ্যাক্সেস টোকেন DPoP-এর পরিবর্তে Bearer-এর token_type বজায় রাখবে। এছাড়াও, Google উত্তরে একটি DPoP-Nonce HTTP হেডার ফেরত দেয়। আপনার ক্লায়েন্টকে এই ননস ক্যাশে করতে হবে এবং পরবর্তী অনুরোধে (যেমন, নতুন অ্যাক্সেস টোকেনের জন্য রিফ্রেশ টোকেন এক্সচেঞ্জ করার সময় অথবা DPoP-সুরক্ষিত API কল করার সময়) DPoP প্রমাণের nonce দাবিতে এটি অন্তর্ভুক্ত করতে হবে। এই আগে ইস্যু করা ননস ব্যবহার করে, আপনি অতিরিক্ত রাউন্ড-ট্রিপ ব্যর্থতা (use_dpop_nonce) এড়াতে পারবেন।

DPoP-বাউন্ড রিফ্রেশ টোকেনের মাধ্যমে করা টোকেন এক্সচেঞ্জের অনুরোধের জন্য DPoP প্রমাণ অন্তর্ভুক্ত করতে হবে।

এক্সচেঞ্জ সম্পূর্ণ না হওয়ার ঘটনা ঘটে যদি প্রত্যাশিত DPoP হেডার না থাকে, ভুল থাকে অথবা প্রমাণে টোকেনের সাথে যুক্ত কী-এর থেকে আলাদা কী ব্যবহার করা হয়। এইসব ক্ষেত্রে, সার্ভার একটি 400 Bad Request সমস্যা দেখায়। DPoP প্রুফে অমিল থাকা htm বা htu দাবি, মেয়াদ শেষ হয়ে যাওয়া iat, আবার ব্যবহার করা jti বা ভুল স্বাক্ষর থাকলে, Google একটি invalid_dpop_proof ত্রুটি কোড দেখায়। যদি DPoP ননসের প্রয়োজন হয়, যেমন রিফ্রেশ টোকেন এক্সচেঞ্জের সময় এবং DPoP প্রমাণে nonce দাবি না থাকে অথবা ননসের ভ্যালু সার্ভারের কাছে গ্রহণযোগ্য না হয় (যেমন, এটির মেয়াদ শেষ হয়ে গেছে, আগে থেকেই ব্যবহার করা হয়েছে অথবা ভুল), তাহলে Google একটি use_dpop_nonce ত্রুটি কোড সহ DPoP-Nonce HTTP হেডার পাঠায় যাতে নতুন ননস থাকে এবং আপনি পরবর্তী অনুরোধে সেটি ব্যবহার করতে পারেন। অন্যান্য ব্যর্থতার ক্ষেত্রে invalid_grant রিটার্ন করা হতে পারে।

Google এই অনুরোধের উত্তর হিসেবে একটি JSON অবজেক্ট পাঠায়, যার মধ্যে স্বল্পমেয়াদী অ্যাক্সেস টোকেন ও রিফ্রেশ টোকেন থাকে। মনে রাখবেন, আপনার অ্যাপ্লিকেশন Google-এর অনুমোদন সার্ভারে করা প্রাথমিক অনুরোধে access_type প্যারামিটার offline হিসেবে সেট করলে তবেই রিফ্রেশ টোকেন ফেরত দেওয়া হয়।

উত্তরে নিম্নলিখিত ফিল্ড রয়েছে:

ফিল্ড
access_token Google API অনুরোধ অনুমোদন করার জন্য আপনার অ্যাপ্লিকেশন যে টোকেন পাঠায়।
expires_in অ্যাক্সেস টোকেনের বাকি মেয়াদ সেকেন্ডে।
refresh_token নতুন অ্যাক্সেস টোকেন পাওয়ার জন্য আপনি যে টোকেন ব্যবহার করতে পারবেন। ব্যবহারকারী অ্যাক্সেস প্রত্যাহার না করা বা রিফ্রেশ টোকেনের মেয়াদ শেষ না হওয়া পর্যন্ত রিফ্রেশ টোকেন বৈধ থাকে। DPoP ব্যবহার করা হলে, DPoP প্রমাণে স্বাক্ষর করার জন্য ব্যবহৃত ব্যক্তিগত কী-এর সাথে রিফ্রেশ টোকেনটি বাউন্ড করা থাকে। আবার, আপনি Google-এর অনুমোদন সার্ভারে প্রাথমিক অনুরোধে access_type প্যারামিটার offline-এ সেট করলে তবেই এই ফিল্ডটি এই উত্তরে উপস্থিত থাকে।
refresh_token_expires_in সেকেন্ডে রিফ্রেশ টোকেনের বাকি থাকা লাইফটাইম। এই ভ্যালু তখনই সেট করা হয় যখন ব্যবহারকারী সময়-ভিত্তিক অ্যাক্সেস দেন।
scope access_token-এর মাধ্যমে মঞ্জুর করা অ্যাক্সেসের স্কোপ স্পেস-ডিলিমিটেড, ছোট ও বড় হাতের অক্ষরের মধ্যে পার্থক্য করা হয় এমন স্ট্রিংয়ের তালিকা হিসেবে প্রকাশ করা হয়।
token_type ফেরত আসা টোকেনের ধরন। DPoP ব্যবহার করা হলেও, এই ভ্যালু সবসময় Bearer হয়।

DPoP ব্যবহার করা হলে, নিম্নলিখিত স্নিপেটে সফল উত্তরের হেডার ও বডির একটি নমুনা দেখানো হয়েছে:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

সমস্যা

অ্যাক্সেস টোকেনের জন্য অথরাইজেশন কোড এক্সচেঞ্জ করার সময় আপনি প্রত্যাশিত উত্তরের পরিবর্তে নিম্নলিখিত সমস্যার সম্মুখীন হতে পারেন। এই বিভাগে সাধারণ ত্রুটি কোড এবং সাজেস্ট করা সমাধান তালিকাভুক্ত করা হয়েছে।

invalid_grant

প্রদান করা অনুমোদন কোডটি ভুল বা ভুল ফর্ম্যাটে আছে। ব্যবহারকারীকে আবার সম্মতি দেওয়ার জন্য প্রম্পট করতে, OAuth প্রসেস রিস্টার্ট করে নতুন কোডের অনুরোধ করুন।

ধাপ ৬: ব্যবহারকারীরা কোন কোন স্কোপে অ্যাক্সেস দিয়েছেন তা চেক করুন

একাধিক অনুমতির (স্কোপ) অনুরোধ করলে, ব্যবহারকারীরা আপনার অ্যাপকে সেগুলির সবকটি অ্যাক্সেস নাও দিতে পারেন। আপনার অ্যাপকে অবশ্যই যাচাই করতে হবে যে কোন কোন স্কোপ আসলে মঞ্জুর করা হয়েছে এবং কিছু অনুমতি অস্বীকার করা হলে পরিস্থিতি সুন্দরভাবে সামলাতে হবে, সাধারণত সেইসব অস্বীকার করা স্কোপের উপর নির্ভর করে ফিচারগুলি বন্ধ করে দিয়ে।

তবে, কিছু ব্যতিক্রম আছে। Google Workspace Enterprise অ্যাপ, যেগুলি ডোমেন-ব্যাপী কর্তৃত্বের ডেলিগেশন-এর সাথে যুক্ত, অথবা বিশ্বস্ত হিসেবে চিহ্নিত, সেগুলি গ্র্যানুলার অনুমতি সংক্রান্ত সম্মতি স্ক্রিন বাইপাস করে। এইসব অ্যাপের ক্ষেত্রে, ব্যবহারকারীরা গ্র্যানুলার অনুমতি সংক্রান্ত সম্মতি স্ক্রিন দেখতে পাবেন না। পরিবর্তে, আপনার অ্যাপ অনুরোধ করা সব স্কোপ পাবে অথবা কিছুই পাবে না।

আরও বিস্তারিত তথ্যের জন্য, কীভাবে গ্র্যানুলার অনুমতি ম্যানেজ করতে হয় দেখুন।

PHP

ব্যবহারকারী কোন কোন স্কোপে অ্যাক্সেস দিয়েছেন তা চেক করতে, getGrantedScope() পদ্ধতি ব্যবহার করুন:

// Space-separated string of granted scopes if it exists, otherwise null.
$granted_scopes = $client->getOAuth2Service()->getGrantedScope();

// Determine which scopes user granted and build a dictionary
$granted_scopes_dict = [
  'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
  'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
];

Python

ফেরত আসা credentials অবজেক্টে granted_scopes প্রপার্টি আছে, যা হল ব্যবহারকারী আপনার অ্যাপকে যেসব স্কোপের অনুমতি দিয়েছেন তার তালিকা।

credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'granted_scopes': credentials.granted_scopes}

ব্যবহারকারী আপনার অ্যাপকে কোন কোন স্কোপের অনুমতি দিয়েছেন তা নিম্নলিখিত ফাংশন চেক করে।

def check_granted_scopes(credentials):
  features = {}
  if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['granted_scopes']:
    features['drive'] = True
  else:
    features['drive'] = False

  if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']:
    features['calendar'] = True
  else:
    features['calendar'] = False

  return features

Ruby

একসাথে একাধিক স্কোপের জন্য অনুরোধ করার সময়, credentials অবজেক্টের scope প্রপার্টির মাধ্যমে কোন কোন স্কোপের অনুমতি দেওয়া হয়েছে তা চেক করুন।

# User authorized the request. Now, check which scopes were granted.
if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY)
  # User authorized read-only Drive activity permission.
  # Calling the APIs, etc
else
  # User didn't authorize read-only Drive activity permission.
  # Update UX and application accordingly
end

# Check if user authorized Calendar read permission.
if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY)
  # User authorized Calendar read permission.
  # Calling the APIs, etc.
else
  # User didn't authorize Calendar read permission.
  # Update UX and application accordingly
end

Node.js

একসাথে একাধিক স্কোপের অনুরোধ করার সময়, tokens অবজেক্টের scope প্রপার্টির মাধ্যমে কোন স্কোপগুলি দেওয়া হয়েছে তা চেক করুন।

// User authorized the request. Now, check which scopes were granted.
if (tokens.scope.includes('https://www.googleapis.com/auth/drive.metadata.readonly'))
{
  // User authorized read-only Drive activity permission.
  // Calling the APIs, etc.
}
else
{
  // User didn't authorize read-only Drive activity permission.
  // Update UX and application accordingly
}

// Check if user authorized Calendar read permission.
if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
{
  // User authorized Calendar read permission.
  // Calling the APIs, etc.
}
else
{
  // User didn't authorize Calendar read permission.
  // Update UX and application accordingly
}

HTTP/REST

ব্যবহারকারী আপনার অ্যাপ্লিকেশনকে কোনও নির্দিষ্ট স্কোপে অ্যাক্সেস দিয়েছেন কিনা তা চেক করতে, অ্যাক্সেস টোকেন রেসপন্সে scope ফিল্ডটি পরীক্ষা করুন। access_token-এর মাধ্যমে মঞ্জুর করা অ্যাক্সেসের স্কোপ স্পেস-ডিলিমিটেড, ছোট ও বড় হাতের অক্ষরের মধ্যে পার্থক্য করা হয় এমন স্ট্রিংয়ের তালিকা হিসেবে প্রকাশ করা হয়।

যেমন, অ্যাক্সেস টোকেন সংক্রান্ত উত্তরের নিম্নলিখিত নমুনা থেকে বোঝা যায় যে ব্যবহারকারী আপনার অ্যাপ্লিকেশনকে শুধু-পঠনযোগ্য Drive অ্যাক্টিভিটি ও Calendar ইভেন্ট সংক্রান্ত অনুমতি দিয়েছেন:

  {
    "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
    "expires_in": 3920,
    "token_type": "Bearer",
    "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
    "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
  }

Google API কল করুন

PHP

নিম্নলিখিত ধাপগুলি সম্পূর্ণ করে Google API কল করার জন্য অ্যাক্সেস টোকেন ব্যবহার করুন:

  1. নতুন Google\Client অবজেক্টে অ্যাক্সেস টোকেন প্রয়োগ করার প্রয়োজন হলে — যেমন, আপনি যদি ব্যবহারকারীর সেশনে অ্যাক্সেস টোকেন সেভ করে থাকেন — তাহলে setAccessToken পদ্ধতি ব্যবহার করুন:
    $client->setAccessToken($access_token);
  2. আপনি যে API কল করতে চান তার জন্য একটি পরিষেবা অবজেক্ট তৈরি করুন। আপনি যে API কল করতে চান তার জন্য কনস্ট্রাক্টরে অনুমোদিত Google\Client অবজেক্ট প্রদান করে আপনি একটি পরিষেবা অবজেক্ট তৈরি করেন। যেমন, Drive API কল করতে:
    $drive = new Google\Service\Drive($client);
  3. পরিষেবা অবজেক্টের দেওয়া ইন্টারফেস ব্যবহার করে API পরিষেবার কাছে অনুরোধ করুন। যেমন, যাচাই করা ব্যবহারকারীর Google Drive-এ ফাইলের তালিকা তৈরি করতে:
    $files = $drive->files->listFiles(array());

Python

অ্যাক্সেস টোকেন পাওয়ার পরে, আপনার অ্যাপ্লিকেশন সেই টোকেন ব্যবহার করে কোনও নির্দিষ্ট ব্যবহারকারীর অ্যাকাউন্ট বা পরিষেবা অ্যাকাউন্টের হয়ে API অনুরোধ অনুমোদন করতে পারে। আপনি যে API কল করতে চান সেটির জন্য পরিষেবা অবজেক্ট তৈরি করতে ব্যবহারকারী-নির্দিষ্ট অনুমোদন সংক্রান্ত ক্রেডেনশিয়াল ব্যবহার করুন এবং তারপরে সেই অবজেক্ট ব্যবহার করে অনুমোদিত API অনুরোধ করুন।

  1. আপনি যে API কল করতে চান তার জন্য একটি পরিষেবা অবজেক্ট তৈরি করুন। আপনি API-এর নাম ও ভার্সন এবং ব্যবহারকারীর ক্রেডেনশিয়াল সহ googleapiclient.discovery লাইব্রেরির build পদ্ধতি কল করে একটি পরিষেবা অবজেক্ট তৈরি করেন: যেমন, Drive API-এর ভার্সন ৩ কল করতে:
    from googleapiclient.discovery import build
    
    drive = build('drive', 'v2', credentials=credentials)
  2. পরিষেবা অবজেক্টের মাধ্যমে প্রদান করা ইন্টারফেস ব্যবহার করে API পরিষেবায় অনুরোধ করুন। যেমন, যাচাই করা ব্যবহারকারীর Google Drive-এ ফাইলের তালিকা তৈরি করতে:
    files = drive.files().list().execute()

Ruby

অ্যাক্সেস টোকেন পাওয়ার পরে, আপনার অ্যাপ্লিকেশন সেই টোকেন ব্যবহার করে কোনও নির্দিষ্ট ব্যবহারকারীর অ্যাকাউন্ট বা পরিষেবা অ্যাকাউন্টের হয়ে API অনুরোধ করতে পারে। আপনি যে API কল করতে চান সেটির জন্য পরিষেবা অবজেক্ট তৈরি করতে ব্যবহারকারী-নির্দিষ্ট অনুমোদন সংক্রান্ত ক্রেডেনশিয়াল ব্যবহার করুন এবং তারপরে সেই অবজেক্ট ব্যবহার করে অনুমোদিত API অনুরোধ করুন।

  1. আপনি যে API কল করতে চান তার জন্য একটি পরিষেবা অবজেক্ট তৈরি করুন। যেমন, Drive API-এর ভার্সন ৩ কল করতে:
    drive = Google::Apis::DriveV3::DriveService.new
  2. পরিষেবায় ক্রেডেনশিয়াল সেট করা:
    drive.authorization = credentials
  3. পরিষেবা অবজেক্টের মাধ্যমে প্রদান করা ইন্টারফেস ব্যবহার করে API পরিষেবায় অনুরোধ করুন। যেমন, যাচাই করা ব্যবহারকারীর Google Drive-এ ফাইল তালিকাভুক্ত করতে:
    files = drive.list_files

বিকল্প হিসেবে, প্রতিটি পদ্ধতির ভিত্তিতে অনুমোদন প্রদান করা যেতে পারে, এর জন্য options প্যারামিটার কোনও পদ্ধতিতে প্রদান করতে হবে:

files = drive.list_files(options: { authorization: credentials })

Node.js

অ্যাক্সেস টোকেন পাওয়ার পরে, সেটি OAuth2 অবজেক্টে সেট করে, Google API কল করতে অবজেক্টটি ব্যবহার করুন। আপনার অ্যাপ্লিকেশন সেই টোকেন ব্যবহার করে কোনও নির্দিষ্ট ব্যবহারকারীর অ্যাকাউন্ট বা পরিষেবা অ্যাকাউন্টের হয়ে API অনুরোধ অনুমোদন করতে পারে। আপনি যে API কল করতে চান তার জন্য একটি পরিষেবা অবজেক্ট তৈরি করুন। যেমন, নিম্নলিখিত কোডটি ব্যবহারকারীর Drive-এ ফাইলের নাম তালিকাভুক্ত করতে Google Drive API ব্যবহার করে।

const { google } = require('googleapis');

// Example of using Google Drive API to list filenames in user's Drive.
const drive = google.drive('v3');
drive.files.list({
  auth: oauth2Client,
  pageSize: 10,
  fields: 'nextPageToken, files(id, name)',
}, (err1, res1) => {
  if (err1) return console.log('The API returned an error: ' + err1);
  const files = res1.data.files;
  if (files.length) {
    console.log('Files:');
    files.map((file) => {
      console.log(`${file.name} (${file.id})`);
    });
  } else {
    console.log('No files found.');
  }
});

HTTP/REST

আপনার অ্যাপ্লিকেশন অ্যাক্সেস টোকেন পাওয়ার পরে, আপনি সেই টোকেন ব্যবহার করে কোনও নির্দিষ্ট ব্যবহারকারীর অ্যাকাউন্টের হয়ে Google API-তে কল করতে পারবেন, যদি API-এর প্রয়োজনীয় অ্যাক্সেসের স্কোপ মঞ্জুর করা হয়ে থাকে। এটি করতে, API-তে অনুরোধ করার সময় access_token কোয়েরি প্যারামিটার বা Authorization HTTP হেডার Bearer ভ্যালু যোগ করে অ্যাক্সেস টোকেন অন্তর্ভুক্ত করুন। সম্ভব হলে, HTTP হেডার ব্যবহার করা ভালো, কারণ কোয়েরি স্ট্রিং সার্ভার লগে দেখা যায়। বেশিরভাগ ক্ষেত্রে, Google API-তে কল সেট-আপ করার জন্য আপনি ক্লায়েন্ট লাইব্রেরি ব্যবহার করতে পারবেন (যেমন, যখন Drive Files API কল করছেন)।

আপনি সব Google API ব্যবহার করে দেখতে এবং OAuth 2.0 Playground-এ সেগুলির স্কোপ দেখতে পারবেন।

HTTP GET-এর উদাহরণ

Authorization: Bearer HTTP হেডার ব্যবহার করে drive.files এন্ডপয়েন্টে (Drive Files API) কল করলে তা নিম্নলিখিত উদাহরণের মতো দেখতে হতে পারে। মনে রাখবেন যে আপনাকে নিজের অ্যাক্সেস টোকেন উল্লেখ করতে হবে:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

access_token কোয়েরি স্ট্রিং প্যারামিটার ব্যবহার করে যাচাই করা ব্যবহারকারীর জন্য একই API-তে কল করার পদ্ধতি এখানে দেওয়া হল:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

curlটি উদাহরণ

আপনি curl কমান্ড-লাইন অ্যাপ্লিকেশনের মাধ্যমে এইসব কমান্ড পরীক্ষা করতে পারবেন। HTTP হেডার বিকল্প ব্যবহার করে এমন একটি উদাহরণ এখানে দেওয়া হল (পছন্দসই):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

অথবা, বিকল্প হিসেবে, কোয়েরি স্ট্রিং প্যারামিটার বিকল্প:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

সম্পূর্ণ উদাহরণ

নিচের উদাহরণে, কোনও ব্যবহারকারী যাচাইকরণ করার পরে এবং ব্যবহারকারীর Drive মেটাডেটা অ্যাক্সেস করার জন্য অ্যাপ্লিকেশনে সম্মতি দেওয়ার পরে ব্যবহারকারীর Google Drive-এ ফাইলের JSON-ফর্ম্যাট করা তালিকা প্রিন্ট করা হয়।

PHP

এই উদাহরণ রান করতে:

  1. API কনসোলে, রিডাইরেক্ট URL-এর তালিকায় লোকাল মেশিনের URL যোগ করুন। যেমন, http://localhost:8080 যোগ করুন।
  2. নতুন ডিরেক্টরি তৈরি করে সেখানে যান। যেমন:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. Composer ব্যবহার করে PHP-এর জন্য Google API ক্লায়েন্ট লাইব্রেরি ইনস্টল করুন:
    composer require google/apiclient:^2.15.0
  4. নিম্নলিখিত কন্টেন্ট সহ index.php এবং oauth2callback.php ফাইল তৈরি করুন।
  5. PHP-এর বিল্ট-ইন টেস্ট ওয়েব সার্ভার ব্যবহার করে উদাহরণটি রান করুন:
    php -S localhost:8080 ~/php-oauth2-example

index.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();
$client->setAuthConfig('client_secret.json');

// User granted permission as an access token is in the session.
if (isset($_SESSION['access_token']) && $_SESSION['access_token'])
{
  $client->setAccessToken($_SESSION['access_token']);
  
  // Check if user granted Drive permission
  if ($_SESSION['granted_scopes_dict']['Drive']) {
    echo "Drive feature is enabled.";
    echo "</br>";
    $drive = new Drive($client);
    $files = array();
    $response = $drive->files->listFiles(array());
    foreach ($response->files as $file) {
        echo "File: " . $file->name . " (" . $file->id . ")";
        echo "</br>";
    }
  } else {
    echo "Drive feature is NOT enabled.";
    echo "</br>";
  }

   // Check if user granted Calendar permission
  if ($_SESSION['granted_scopes_dict']['Calendar']) {
    echo "Calendar feature is enabled.";
    echo "</br>";
  } else {
    echo "Calendar feature is NOT enabled.";
    echo "</br>";
  }
}
else
{
  // Redirect users to outh2call.php which redirects users to Google OAuth 2.0
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>

oauth2callback.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();

// Required, call the setAuthConfig function to load authorization credentials from
// client_secret.json file.
$client->setAuthConfigFile('client_secret.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST']. $_SERVER['PHP_SELF']);

// Required, to set the scope value, call the addScope function.
$client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);

// Enable incremental authorization. Recommended as a best practice.
$client->setIncludeGrantedScopes(true);

// Recommended, offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType("offline");

// Generate a URL for authorization as it doesn't contain code and error
if (!isset($_GET['code']) && !isset($_GET['error']))
{
  // Generate and set state value
  $state = bin2hex(random_bytes(16));
  $client->setState($state);
  $_SESSION['state'] = $state;

  // Generate a url that asks permissions.
  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
}

// User authorized the request and authorization code is returned to exchange access and
// refresh tokens.
if (isset($_GET['code']))
{
  // Check the state value
  if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) {
    die('State mismatch. Possible CSRF attack.');
  }

  // Get access and refresh tokens (if access_type is offline)
  $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);

  /** Save access and refresh token to the session variables.
    * ACTION ITEM: In a production app, you likely want to save the
    *              refresh token in a secure persistent storage instead. */
  $_SESSION['access_token'] = $token;
  $_SESSION['refresh_token'] = $client->getRefreshToken();
  
  // Space-separated string of granted scopes if it exists, otherwise null.
  $granted_scopes = $client->getOAuth2Service()->getGrantedScope();

  // Determine which scopes user granted and build a dictionary
  $granted_scopes_dict = [
    'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
    'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
  ];
  $_SESSION['granted_scopes_dict'] = $granted_scopes_dict;
  
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

// An error response e.g. error=access_denied
if (isset($_GET['error']))
{
  echo "Error: ". $_GET['error'];
}
?>

Python

এই উদাহরণে Flask ফ্রেমওয়ার্ক ব্যবহার করা হয়েছে। এটি http://localhost:8080-এ একটি ওয়েব অ্যাপ্লিকেশন রান করে যা আপনাকে OAuth 2.0 ফ্লো পরীক্ষা করতে দেয়। আপনি সেই URL-এ গেলে, পাঁচটি লিঙ্ক দেখতে পাবেন:

  • Drive API কল করুন: এই লিঙ্কটি এমন একটি পৃষ্ঠাকে নির্দেশ করে যা ব্যবহারকারীরা অনুমতি দিলে একটি নমুনা API অনুরোধ কার্যকর করার চেষ্টা করে। প্রয়োজন হলে, এটি অনুমোদনের ফ্লো শুরু করে। সফল হলে, পৃষ্ঠায় API রেসপন্স দেখানো হয়।
  • Calendar API কল করার জন্য মক পৃষ্ঠা: এই লিঙ্কটি একটি মক পৃষ্ঠাকে নির্দেশ করে যা ব্যবহারকারীরা অনুমতি দিলে একটি নমুনা Calendar API অনুরোধ কার্যকর করার চেষ্টা করে। প্রয়োজন হলে, এটি অনুমোদনের ফ্লো শুরু করে। সফল হলে, পৃষ্ঠায় API রেসপন্স দেখানো হয়।
  • সরাসরি যাচাইকরণ ফ্লো পরীক্ষা করুন: এই লিঙ্কটি এমন একটি পৃষ্ঠার দিকে নির্দেশ করে যা ব্যবহারকারীকে অনুমোদন ফ্লো-এর মাধ্যমে পাঠানোর চেষ্টা করে। অ্যাপটি ব্যবহারকারীর হয়ে অনুমোদিত API অনুরোধ জমা দেওয়ার অনুমতি চায়।
  • বর্তমান ক্রেডেনশিয়াল তুলে নেওয়া: এই লিঙ্কটি এমন একটি পৃষ্ঠার দিকে নির্দেশ করে যা ব্যবহারকারী ইতিমধ্যেই অ্যাপ্লিকেশনকে দেওয়া অনুমতি তুলে নেয়।
  • Flask সেশন ক্রেডেনশিয়াল মুছে দিন: এই লিঙ্ক Flask সেশনে স্টোর করা অনুমোদনের ক্রেডেনশিয়াল মুছে দেয়। এর ফলে, আপনি দেখতে পাবেন যে আপনার অ্যাপকে আগে থেকেই অনুমতি দেওয়া কোনও ব্যবহারকারী নতুন সেশনে API অনুরোধ কার্যকর করার চেষ্টা করলে কী হবে। এছাড়াও, এটি আপনাকে API রেসপন্স দেখতে দেয় যা আপনার অ্যাপ পাবে যদি কোনও ব্যবহারকারী আপনার অ্যাপকে দেওয়া অনুমতি প্রত্যাহার করে নেয় এবং আপনার অ্যাপ এখনও প্রত্যাহার করা অ্যাক্সেস টোকেন সহ অনুরোধ অনুমোদন করার চেষ্টা করে।
# -*- coding: utf-8 -*-

import os
import flask
import json
import requests

import google.oauth2.credentials
import google_auth_oauthlib.flow
import googleapiclient.discovery

# This variable specifies the name of a file that contains the OAuth 2.0
# information for this application, including its client_id and client_secret.
CLIENT_SECRETS_FILE = "client_secret.json"

# The OAuth 2.0 access scope allows for access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly',
          'https://www.googleapis.com/auth/calendar.readonly']
API_SERVICE_NAME = 'drive'
API_VERSION = 'v2'

app = flask.Flask(__name__)
# Note: A secret key is included in the sample so that it works.
# If you use this code in your application, replace this with a truly secret
# key. See https://flask.palletsprojects.com/quickstart/#sessions.
app.secret_key = 'REPLACE ME - this value is here as a placeholder.'

@app.route('/')
def index():
  return print_index_table()

@app.route('/drive')
def drive_api_request():
  if 'credentials' not in flask.session:
    return flask.redirect('authorize')

  features = flask.session['features']

  if features['drive']:
    # Load client secrets from the server-side file.
    with open(CLIENT_SECRETS_FILE, 'r') as f:
        client_config = json.load(f)['web']

    # Load user-specific credentials from browser session storage.
    session_credentials = flask.session['credentials']

    # Reconstruct the credentials object.
    credentials = google.oauth2.credentials.Credentials(
        refresh_token=session_credentials.get('refresh_token'),
        scopes=session_credentials.get('granted_scopes'),
        token=session_credentials.get('token'),
        client_id=client_config.get('client_id'),
        client_secret=client_config.get('client_secret'),
        token_uri=client_config.get('token_uri'))

    drive = googleapiclient.discovery.build(
        API_SERVICE_NAME, API_VERSION, credentials=credentials)

    files = drive.files().list().execute()

    # Save credentials back to session in case access token was refreshed.
    flask.session['credentials'] = credentials_to_dict(credentials)

    return flask.jsonify(**files)
  else:
    # User didn't authorize read-only Drive activity permission.
    return '<p>Drive feature is not enabled.</p>'

@app.route('/calendar')
def calendar_api_request():
  if 'credentials' not in flask.session:
    return flask.redirect('authorize')

  features = flask.session['features']

  if features['calendar']:
    # User authorized Calendar read permission.
    # Calling the APIs, etc.
    return ('<p>User granted the Google Calendar read permission. '+
            'This sample code does not include code to call Calendar</p>')
  else:
    # User didn't authorize Calendar read permission.
    # Update UX and application accordingly
    return '<p>Calendar feature is not enabled.</p>'

@app.route('/authorize')
def authorize():
  # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES)

  # The URI created here must exactly match one of the authorized redirect URIs
  # for the OAuth 2.0 client, which you configured in the API Console. If this
  # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
  # error.
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  authorization_url, state = flow.authorization_url(
      # Enable offline access so that you can refresh an access token without
      # re-prompting the user for permission. Recommended for web server apps.
      access_type='offline',
      # Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes='true')

  # Store the state so the callback can verify the auth server response.
  flask.session['state'] = state

  return flask.redirect(authorization_url)

@app.route('/oauth2callback')
def oauth2callback():
  # Specify the state when creating the flow in the callback so that it can
  # verified in the authorization server response.
  state = flask.session['state']

  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  # Use the authorization server's response to fetch the OAuth 2.0 tokens.
  authorization_response = flask.request.url
  flow.fetch_token(authorization_response=authorization_response)

  # Store credentials in the session.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  credentials = flow.credentials
  
  credentials = credentials_to_dict(credentials)
  flask.session['credentials'] = credentials

  # Check which scopes user granted
  features = check_granted_scopes(credentials)
  flask.session['features'] = features
  return flask.redirect('/')
  
@app.route('/revoke')
def revoke():
  if 'credentials' not in flask.session:
    return ('You need to <a href="/authorize">authorize</a> before ' +
            'testing the code to revoke credentials.')

  # Load client secrets from the server-side file.
  with open(CLIENT_SECRETS_FILE, 'r') as f:
      client_config = json.load(f)['web']

  # Load user-specific credentials from the session.
  session_credentials = flask.session['credentials']

  # Reconstruct the credentials object.
  credentials = google.oauth2.credentials.Credentials(
      refresh_token=session_credentials.get('refresh_token'),
      scopes=session_credentials.get('granted_scopes'),
      token=session_credentials.get('token'),
      client_id=client_config.get('client_id'),
      client_secret=client_config.get('client_secret'),
      token_uri=client_config.get('token_uri'))

  revoke = requests.post('https://oauth2.googleapis.com/revoke',
      params={'token': credentials.token},
      headers = {'content-type': 'application/x-www-form-urlencoded'})

  status_code = getattr(revoke, 'status_code')
  if status_code == 200:
    # Clear the user's session credentials after successful revocation
    if 'credentials' in flask.session:
        del flask.session['credentials']
        del flask.session['features']
    return('Credentials successfully revoked.' + print_index_table())
  else:
    return('An error occurred.' + print_index_table())

@app.route('/clear')
def clear_credentials():
  if 'credentials' in flask.session:
    del flask.session['credentials']
  return ('Credentials have been cleared.<br><br>' +
          print_index_table())

def credentials_to_dict(credentials):
  return {'token': credentials.token,
          'refresh_token': credentials.refresh_token,
          'granted_scopes': credentials.granted_scopes}

def check_granted_scopes(credentials):
  features = {}
  if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['granted_scopes']:
    features['drive'] = True
  else:
    features['drive'] = False

  if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']:
    features['calendar'] = True
  else:
    features['calendar'] = False

  return features

def print_index_table():
  return ('<table>' + 
          '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
          '<td>Go directly to the authorization flow. If there are stored ' +
          '    credentials, you still might not be prompted to reauthorize ' +
          '    the application.</td></tr>' +
          '<tr><td><a href="/drive">Call Drive API directly</a></td>' +
          '<td> Use stored credentials to call the API, you still might not be prompted to reauthorize ' +
          '    the application.</td></tr>' +
          '<tr><td><a href="/calendar">Call Calendar API directly</a></td>' +
          '<td> Use stored credentials to call the API, you still might not be prompted to reauthorize ' +
          '    the application.</td></tr>' + 
          '<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
          '<td>Revoke the access token associated with the current user ' +
          '    session. After revoking credentials, if you go to the test ' +
          '    page, you should see an <code>invalid_grant</code> error.' +
          '</td></tr>' +
          '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
          '<td>Clear the access token currently stored in the user session. ' +
          '    After clearing the token, if you <a href="/authorize">authorize</a> ' +
          '    again, you should go back to the auth flow.' +
          '</td></tr></table>')

if __name__ == '__main__':
  # When running locally, disable OAuthlib's HTTPs verification.
  # ACTION ITEM for developers:
  #     When running in production *do not* leave this option enabled.
  os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

  # This disables the requested scopes and granted scopes check.
  # If users only grant partial request, the warning would not be thrown.
  os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'

  # Specify a hostname and port that are set as a valid redirect URI
  # for your API project in the Google API Console.
  app.run('localhost', 8080, debug=True)

Ruby

এই উদাহরণে Sinatra ফ্রেমওয়ার্ক ব্যবহার করা হয়েছে।

require 'googleauth'
require 'googleauth/web_user_authorizer'
require 'googleauth/stores/redis_token_store'

require 'google/apis/drive_v3'
require 'google/apis/calendar_v3'

require 'sinatra'

configure do
  enable :sessions

  # Required, call the from_file method to retrieve the client ID from a
  # client_secret.json file.
  set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')

  # Required, scope value
  # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
  scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
           'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']

  # Required, Authorizers require a storage instance to manage long term persistence of
  # access and refresh tokens.
  set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)

  # Required, indicate where the API server will redirect the user after the user completes
  # the authorization flow. The redirect URI is required. The value must exactly
  # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
  # configured in the API Console. If this value doesn't match an authorized URI,
  # you will get a 'redirect_uri_mismatch' error.
  set :callback_uri, '/oauth2callback'

  # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
  # from the client_secret.json file. To get these credentials for your application, visit
  # https://console.cloud.google.com/apis/credentials.
  set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope,
                          settings.token_store, callback_uri: settings.callback_uri)
end

get '/' do
  # NOTE: Assumes the user is already authenticated to the app
  user_id = request.session['user_id']

  # Fetch stored credentials for the user from the given request session.
  # nil if none present
  credentials = settings.authorizer.get_credentials(user_id, request)

  if credentials.nil?
    # Generate a url that asks the user to authorize requested scope(s).
    # Then, redirect user to the url.
    redirect settings.authorizer.get_authorization_url(request: request)
  end
  
  # User authorized the request. Now, check which scopes were granted.
  if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY)
    # User authorized read-only Drive activity permission.
    # Example of using Google Drive API to list filenames in user's Drive.
    drive = Google::Apis::DriveV3::DriveService.new
    files = drive.list_files(options: { authorization: credentials })
    "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
  else
    # User didn't authorize read-only Drive activity permission.
    # Update UX and application accordingly
  end

  # Check if user authorized Calendar read permission.
  if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY)
    # User authorized Calendar read permission.
    # Calling the APIs, etc.
  else
    # User didn't authorize Calendar read permission.
    # Update UX and application accordingly
  end
end

# Receive the callback from Google's OAuth 2.0 server.
get '/oauth2callback' do
  # Handle the result of the oauth callback. Defers the exchange of the code by
  # temporarily stashing the results in the user's session.
  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url
end

Node.js

এই উদাহরণ রান করতে:

  1. API কনসোলে, রিডাইরেক্ট URL-এর তালিকায় লোকাল মেশিনের URL যোগ করুন। যেমন, http://localhost যোগ করুন।
  2. আপনার কাছে Node.js-এর রক্ষণাবেক্ষণ LTS, অ্যাক্টিভ LTS বা বর্তমান রিলিজ ইনস্টল করা আছে কিনা তা নিশ্চিত করুন।
  3. নতুন ডিরেক্টরি তৈরি করে সেখানে যান। যেমন:
    mkdir ~/nodejs-oauth2-example
    cd ~/nodejs-oauth2-example
  4. npm ব্যবহার করে Node.js-এর জন্য Google API Client Library ইনস্টল করুন:
    npm install googleapis
  5. নিম্নলিখিত কন্টেন্ট সহ main.js ফাইল তৈরি করুন।
  6. উদাহরণটি চালান:
    node .\main.js

main.js

const http = require('http');
const https = require('https');
const url = require('url');
const { google } = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
 * To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

/* Global variable that stores user credential in this code example.
 * ACTION ITEM for developers:
 *   Store user's refresh token in your data store if
 *   incorporating this code into your real app.
 *   For more information on handling refresh tokens,
 *   see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
 */
let userCredential = null;

async function main() {
  const app = express();

  app.use(session({
    secret: 'your_secure_secret_key', // Replace with a strong secret
    resave: false,
    saveUninitialized: false,
  }));

  // Example on redirecting user to Google's OAuth 2.0 server.
  app.get('/', async (req, res) => {
    // Generate a secure random state value.
    const state = crypto.randomBytes(32).toString('hex');
    // Store state in the session
    req.session.state = state;

    // Generate a url that asks permissions for the Drive activity and Google Calendar scope
    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true,
      // Include the state parameter to reduce the risk of CSRF attacks.
      state: state
    });

    res.redirect(authorizationUrl);
  });

  // Receive the callback from Google's OAuth 2.0 server.
  app.get('/oauth2callback', async (req, res) => {
    // Handle the OAuth 2.0 server response
    let q = url.parse(req.url, true).query;

    if (q.error) { // An error response e.g. error=access_denied
      console.log('Error:' + q.error);
    } else if (q.state !== req.session.state) { //check state value
      console.log('State mismatch. Possible CSRF attack');
      res.end('State mismatch. Possible CSRF attack');
    } else { // Get access and refresh tokens (if access_type is offline)
      let { tokens } = await oauth2Client.getToken(q.code);
      oauth2Client.setCredentials(tokens);

      /** Save credential to the global variable in case access token was refreshed.
        * ACTION ITEM: In a production app, you likely want to save the refresh token
        *              in a secure persistent database instead. */
      userCredential = tokens;
      
      // User authorized the request. Now, check which scopes were granted.
      if (tokens.scope.includes('https://www.googleapis.com/auth/drive.metadata.readonly'))
      {
        // User authorized read-only Drive activity permission.
        // Example of using Google Drive API to list filenames in user's Drive.
        const drive = google.drive('v3');
        drive.files.list({
          auth: oauth2Client,
          pageSize: 10,
          fields: 'nextPageToken, files(id, name)',
        }, (err1, res1) => {
          if (err1) return console.log('The API returned an error: ' + err1);
          const files = res1.data.files;
          if (files.length) {
            console.log('Files:');
            files.map((file) => {
              console.log(`${file.name} (${file.id})`);
            });
          } else {
            console.log('No files found.');
          }
        });
      }
      else
      {
        // User didn't authorize read-only Drive activity permission.
        // Update UX and application accordingly
      }

      // Check if user authorized Calendar read permission.
      if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
      {
        // User authorized Calendar read permission.
        // Calling the APIs, etc.
      }
      else
      {
        // User didn't authorize Calendar read permission.
        // Update UX and application accordingly
      }
    }
  });

  // Example on revoking a token
  app.get('/revoke', async (req, res) => {
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;

    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };

    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });

    postReq.on('error', error => {
      console.log(error)
    });

    // Post the request with data
    postReq.write(postData);
    postReq.end();
  });


  const server = http.createServer(app);
  server.listen(8080);
}
main().catch(console.error);

HTTP/REST

এই Python উদাহরণে OAuth 2.0 ওয়েব ফ্লো দেখানোর জন্য Flask ফ্রেমওয়ার্ক এবং Requests লাইব্রেরি ব্যবহার করা হয়েছে। এই ফ্লোয়ের জন্য Python-এর Google API ক্লায়েন্ট লাইব্রেরি ব্যবহার করার সাজেশন দিই। (Python ট্যাবের উদাহরণে ক্লায়েন্ট লাইব্রেরি ব্যবহার করা হয়।)

import json
import flask
import requests

app = flask.Flask(__name__)

# To get these credentials (CLIENT_ID CLIENT_SECRET) and for your application, visit
# https://console.cloud.google.com/apis/credentials.
CLIENT_ID = '123456789.apps.googleusercontent.com'
CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app

# Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly'

# Indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
REDIRECT_URI = 'http://example.com/oauth2callback'

@app.route('/')
def index():
  if 'credentials' not in flask.session:
    return flask.redirect(flask.url_for('oauth2callback'))

  credentials = json.loads(flask.session['credentials'])

  if credentials['expires_in'] <= 0:
    return flask.redirect(flask.url_for('oauth2callback'))
  else: 
    # User authorized the request. Now, check which scopes were granted.
    if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['scope']:
      # User authorized read-only Drive activity permission.
      # Example of using Google Drive API to list filenames in user's Drive.
      headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
      req_uri = 'https://www.googleapis.com/drive/v2/files'
      r = requests.get(req_uri, headers=headers).text
    else:
      # User didn't authorize read-only Drive activity permission.
      # Update UX and application accordingly
      r = 'User did not authorize Drive permission.'

    # Check if user authorized Calendar read permission.
    if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['scope']:
      # User authorized Calendar read permission.
      # Calling the APIs, etc.
      r += 'User authorized Calendar permission.'
    else:
      # User didn't authorize Calendar read permission.
      # Update UX and application accordingly
      r += 'User did not authorize Calendar permission.'

  return r

@app.route('/oauth2callback')
def oauth2callback():
  if 'code' not in flask.request.args:
    state = str(uuid.uuid4())
    flask.session['state'] = state
    # Generate a url that asks permissions for the Drive activity
    # and Google Calendar scope. Then, redirect user to the url.
    auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI,
                                                                          SCOPE, state)
    return flask.redirect(auth_uri)
  else:
    if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']:
      return 'State mismatch. Possible CSRF attack.', 400

    auth_code = flask.request.args.get('code')
    data = {'code': auth_code,
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'redirect_uri': REDIRECT_URI,
            'grant_type': 'authorization_code'}

    # Exchange authorization code for access and refresh tokens (if access_type is offline)
    r = requests.post('https://oauth2.googleapis.com/token', data=data)
    flask.session['credentials'] = r.text
    return flask.redirect(flask.url_for('index'))

if __name__ == '__main__':
  import uuid
  app.secret_key = str(uuid.uuid4())
  app.debug = False
  app.run()

রিডাইরেক্ট URI যাচাইকরণ সংক্রান্ত নিয়ম

ডেভেলপারদের অ্যাপ্লিকেশন সুরক্ষিত রাখতে সাহায্য করার জন্য Google রিডাইরেক্ট URI-তে নিম্নলিখিত যাচাইকরণ সংক্রান্ত নিয়ম প্রয়োগ করে। আপনার রিডাইরেক্ট URI-কে এইসব নিয়ম মেনে চলতে হবে। এইসব নিয়মে ব্যবহৃত ডোমেন, হোস্ট, পাথ, কোয়েরি, স্কিম ও ইউজারইনফোর সংজ্ঞা জানতে RFC 3986 বিভাগ ৩ দেখুন।

যাচাইকরণের নিয়ম
স্কিম

রিডাইরেক্ট URI-তে অবশ্যই HTTPS স্কিম ব্যবহার করতে হবে, সাধারণ HTTP নয়। লোকালহোস্ট URI (লোকালহোস্ট IP অ্যাড্রেস URI সহ) এই নিয়মের আওতাভুক্ত নয়।

হোস্ট

হোস্ট র IP অ্যাড্রেস হতে পারবে না। Localhost IP অ্যাড্রেস এই নিয়মের আওতাভুক্ত নয়।

ডোমেন
  • হোস্ট TLD (টপ লেভেল ডোমেন) অবশ্যই পাবলিক সাফিক্স তালিকার অন্তর্গত হতে হবে।
  • হোস্ট ডোমেন “googleusercontent.com” হতে পারবে না।
  • অ্যাপের মালিকানায় ডোমেন না থাকলে, রিডাইরেক্ট URI-তে URL ছোট করার ডোমেন (যেমন, goo.gl) থাকতে পারবে না। এছাড়াও, কোনও অ্যাপ যদি শর্টনার ডোমেনের মালিক হয় এবং সেই ডোমেনে রিডাইরেক্ট করার বিকল্প বেছে নেয়, তাহলে সেই রিডাইরেক্ট URI-এর পাথে “/google-callback/” থাকতে হবে অথবা সেটি “/google-callback” দিয়ে শেষ হতে হবে।
  • Userinfo

    রিডাইরেক্ট URI-তে ব্যবহারকারীর তথ্য সংক্রান্ত সাবকম্পোনেন্ট থাকতে পারবে না।

    পাথ

    রিডাইরেক্ট URI-তে পাথ ট্র্যাভারসাল (ডিরেক্টরি ব্যাকট্র্যাকিংও বলা হয়) থাকলে চলবে না, যা “/..” বা “\..” বা তাদের URL এনকোডিং দ্বারা দেখানো হয়।

    কোয়েরি

    রিডাইরেক্ট URI-তে ওপেন রিডাইরেক্ট থাকতে পারবে না।

    ফ্র্যাগমেন্ট

    রিডাইরেক্ট URI-তে ফ্র্যাগমেন্ট কম্পোনেন্ট থাকতে পারে না।

    চরিত্র রিডাইরেক্ট URI-তে নির্দিষ্ট কিছু অক্ষর থাকতে পারবে না, যার মধ্যে রয়েছে:
    • ওয়াইল্ডকার্ড অক্ষর ('*')
    • প্রিন্ট করা যায় না এমন ASCII অক্ষর
    • ভুল শতাংশ এনকোডিং (যেকোনও শতাংশ এনকোডিং যা URL-এনকোডিং অনুসরণ করে না দুটি হেক্সাডেসিমেল সংখ্যা সহ শতাংশ চিহ্নের ফর্ম)
    • নাল অক্ষর (একটি এনকোড করা NULL অক্ষর, যেমন, %00, %C0%80)

    ইনক্রিমেন্টাল অনুমোদন

    OAuth 2.0 প্রোটোকলে, আপনার অ্যাপ রিসোর্স অ্যাক্সেস করার জন্য অনুমোদনের অনুরোধ করে, যা স্কোপের মাধ্যমে শনাক্ত করা হয়। রিসোর্সের প্রয়োজন হলে সেই সময় অনুমোদনের অনুরোধ করাকে ব্যবহারকারীর অভিজ্ঞতা সংক্রান্ত সেরা পদ্ধতি হিসেবে বিবেচনা করা হয়। সেই পদ্ধতি চালু করতে, Google-এর অথরাইজেশন সার্ভার ইনক্রিমেন্টাল অথরাইজেশনকে সমর্থন করে। এই ফিচার আপনাকে প্রয়োজন অনুযায়ী স্কোপের অনুরোধ করতে দেয় এবং ব্যবহারকারী নতুন স্কোপের জন্য অনুমতি দিলে, একটি অথরাইজেশন কোড ফেরত দেয় যা ব্যবহারকারী প্রোজেক্টকে যেসব স্কোপের অনুমতি দিয়েছেন সেগুলি সহ টোকেনের সাথে এক্সচেঞ্জ করা যেতে পারে।

    যেমন, কোনও অ্যাপ যদি মানুষকে মিউজিক ট্র্যাকের স্যাম্পেল নিতে এবং মিক্স তৈরি করতে দেয়, তাহলে সাইন-ইন করার সময় খুব কম রিসোর্স প্রয়োজন হতে পারে, সম্ভবত সাইন-ইন করা ব্যক্তির নাম ছাড়া আর কিছুই প্রয়োজন হবে না। তবে, সম্পূর্ণ মিক্স সেভ করতে হলে, তাদের Google Drive-এর অ্যাক্সেস প্রয়োজন হবে। অধিকাংশ মানুষই স্বাভাবিক মনে করবেন যদি অ্যাপের যখন প্রয়োজন তখনই শুধু Google Drive-এর অ্যাক্সেস চাওয়া হয়।

    এই ক্ষেত্রে, সাইন-ইন করার সময় অ্যাপটি সাধারণ সাইন-ইন করার জন্য openid এবং profile স্কোপের অনুরোধ করতে পারে এবং তারপর কোনও মিক্স সেভ করার জন্য প্রথম অনুরোধ করার সময় https://www.googleapis.com/auth/drive.file স্কোপের অনুরোধ করতে পারে।

    ইনক্রিমেন্টাল অনুমোদন প্রয়োগ করতে, আপনাকে অ্যাক্সেস টোকেনের অনুরোধ করার জন্য সাধারণ ফ্লো সম্পূর্ণ করতে হবে তবে নিশ্চিত করুন যে অনুমোদনের অনুরোধে আগে মঞ্জুর করা স্কোপ অন্তর্ভুক্ত আছে। এই পদ্ধতি আপনার অ্যাপকে একাধিক অ্যাক্সেস টোকেন ম্যানেজ করার প্রয়োজন থেকে মুক্তি দেয়।

    ইনক্রিমেন্টাল অনুমোদন থেকে পাওয়া অ্যাক্সেস টোকেনের ক্ষেত্রে নিম্নলিখিত নিয়ম প্রযোজ্য:

    • নতুন, সম্মিলিত অনুমোদনের মধ্যে অন্তর্ভুক্ত যেকোনও স্কোপের সাথে সম্পর্কিত রিসোর্স অ্যাক্সেস করতে টোকেনটি ব্যবহার করা যেতে পারে।
    • অ্যাক্সেস টোকেন পাওয়ার জন্য আপনি যখন সম্মিলিত অনুমোদনের জন্য রিফ্রেশ টোকেন ব্যবহার করেন, তখন অ্যাক্সেস টোকেনটি সম্মিলিত অনুমোদনের প্রতিনিধিত্ব করে এবং উত্তরে অন্তর্ভুক্ত scope মানগুলির যেকোনও একটির জন্য ব্যবহার করা যেতে পারে।
    • সম্মিলিত অনুমোদনের মধ্যে সেইসব স্কোপ অন্তর্ভুক্ত থাকে যেগুলি ব্যবহারকারী API প্রোজেক্টকে দিয়েছেন, এমনকি যদি আলাদা আলাদা ক্লায়েন্ট থেকে অনুমোদনের অনুরোধ করা হয়ে থাকে। যেমন, কোনও ব্যবহারকারী যদি কোনও অ্যাপ্লিকেশনের ডেস্কটপ ক্লায়েন্ট ব্যবহার করে একটি স্কোপে অ্যাক্সেস দেন এবং তারপরে মোবাইল ক্লায়েন্টের মাধ্যমে একই অ্যাপ্লিকেশনে আরেকটি স্কোপে অ্যাক্সেস দেন, তাহলে সম্মিলিত অনুমোদনে দুটি স্কোপই অন্তর্ভুক্ত থাকবে।
    • আপনি যদি এমন কোনও টোকেন প্রত্যাহার করেন যা একটি সম্মিলিত অনুমোদনকে উপস্থাপন করে, তাহলে সংশ্লিষ্ট ব্যবহারকারীর পক্ষে সেই অনুমোদনের সমস্ত স্কোপের অ্যাক্সেস একই সাথে প্রত্যাহার করা হয়।

    ধাপ ১: অনুমোদন সেট করুন Google-এর OAuth 2.0 সার্ভারে রিডাইরেক্ট করুন-এ দেওয়া ভাষা-নির্দিষ্ট কোড স্যাম্পেলগুলি সবই ইনক্রিমেন্টাল অনুমোদন ব্যবহার করে। এছাড়াও, ইনক্রিমেন্টাল অনুমোদন ব্যবহার করার জন্য আপনাকে যে কোড যোগ করতে হবে তা নিম্নলিখিত কোড নমুনা থেকে দেখতে পাবেন।

    PHP

    $client->setIncludeGrantedScopes(true);

    Python

    Python-এ, include_granted_scopes কীওয়ার্ড আর্গুমেন্ট true-এ সেট করুন যাতে নিশ্চিত করা যায় যে অনুমোদনের অনুরোধে আগে অনুমোদিত স্কোপ অন্তর্ভুক্ত আছে। খুবই সম্ভব যে include_granted_scopes আপনার সেট করা একমাত্র কীওয়ার্ড আর্গুমেন্ট হবে না, যেমন নিচের উদাহরণে দেখানো হয়েছে।

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    Ruby

    auth_client.update!(
      :additional_parameters => {"include_granted_scopes" => "true"}
    )

    Node.js

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });

    HTTP/REST

    GET https://accounts.google.com/o/oauth2/v2/auth?
      client_id=your_client_id&
      response_type=code&
      state=state_parameter_passthrough_value&
      scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
      redirect_uri=https%3A//developers.google.com/oauthplayground&
      prompt=consent&
      include_granted_scopes=true

    অ্যাক্সেস টোকেন রিফ্রেশ করা (অফলাইন অ্যাক্সেস)

    অ্যাক্সেস টোকেনের মেয়াদ নির্দিষ্ট সময় অন্তর শেষ হয়ে যায় এবং সংশ্লিষ্ট API অনুরোধের জন্য ক্রেডেনশিয়াল ভুল হয়ে যায়। আপনি ব্যবহারকারীকে অনুমতি দেওয়ার জন্য প্রম্পট না করেই অ্যাক্সেস টোকেন রিফ্রেশ করতে পারবেন (এর মধ্যে ব্যবহারকারী উপস্থিত না থাকলেও পড়বে), যদি আপনি টোকেনের সাথে যুক্ত স্কোপে অফলাইন অ্যাক্সেসের অনুরোধ করে থাকেন।

    • আপনি Google API ক্লায়েন্ট লাইব্রেরি ব্যবহার করলে, অফলাইন অ্যাক্সেসের জন্য সেই অবজেক্ট কনফিগার করা পর্যন্ত ক্লায়েন্ট অবজেক্ট প্রয়োজন অনুযায়ী অ্যাক্সেস টোকেন রিফ্রেশ করে।
    • আপনি ক্লায়েন্ট লাইব্রেরি ব্যবহার না করলে, ব্যবহারকারীকে Google-এর OAuth 2.0 সার্ভারে রিডাইরেক্ট করার সময় আপনাকে access_type HTTP কোয়েরি প্যারামিটার offline-এ সেট করতে হবে। সেই ক্ষেত্রে, আপনি অ্যাক্সেস টোকেনের জন্য অনুমোদন কোড এক্সচেঞ্জ করলে Google-এর অনুমোদন সার্ভার একটি রিফ্রেশ টোকেন রিটার্ন করে। তারপরে, অ্যাক্সেস টোকেনের মেয়াদ শেষ হয়ে গেলে (বা অন্য যেকোনও সময়), আপনি নতুন অ্যাক্সেস টোকেন পেতে রিফ্রেশ টোকেন ব্যবহার করতে পারবেন।

    ব্যবহারকারী উপস্থিত না থাকলে, Google API অ্যাক্সেস করতে হবে এমন যেকোনও অ্যাপ্লিকেশনের জন্য অফলাইন অ্যাক্সেসের অনুরোধ করা প্রয়োজন। যেমন, ব্যাক-আপ পরিষেবা প্রদান করে বা আগে থেকে নির্ধারিত সময়ে অ্যাকশন এক্সিকিউট করে এমন কোনও অ্যাপকে ব্যবহারকারী উপস্থিত না থাকলে অ্যাক্সেস টোকেন রিফ্রেশ করতে হবে। অ্যাক্সেসের ডিফল্ট স্টাইলকে online বলা হয়।

    অনুমতি দেওয়ার প্রসেস চলাকালীন সার্ভার-সাইড ওয়েব অ্যাপ্লিকেশন, ইনস্টল করা অ্যাপ্লিকেশন এবং ডিভাইস, সবগুলিই রিফ্রেশ টোকেন পায়। ক্লায়েন্ট-সাইড (জাভাস্ক্রিপ্ট) ওয়েব অ্যাপ্লিকেশনে সাধারণত রিফ্রেশ টোকেন ব্যবহার করা হয় না।

    PHP

    আপনার অ্যাপ্লিকেশনের Google API-তে অফলাইন অ্যাক্সেসের প্রয়োজন হলে, API ক্লায়েন্টের অ্যাক্সেস offlineটাইপ সেট করুন:

    $client->setAccessType("offline");

    কোনও ব্যবহারকারী অনুরোধ করা স্কোপে অফলাইন অ্যাক্সেস দেওয়ার পরে, ব্যবহারকারী অফলাইনে থাকলেও আপনি API ক্লায়েন্ট ব্যবহার করে তার হয়ে Google API অ্যাক্সেস করা চালিয়ে যেতে পারবেন। ক্লায়েন্ট অবজেক্ট প্রয়োজন অনুযায়ী অ্যাক্সেস টোকেন রিফ্রেশ করবে।

    Python

    Python-এ, access_type কীওয়ার্ড আর্গুমেন্টকে offline হিসেবে সেট করুন, যাতে আপনি অ্যাক্সেস টোকেন রিফ্রেশ করতে পারেন এবং ব্যবহারকারীকে আবার অনুমতি সংক্রান্ত প্রম্পট দেখাতে না হয়। এটি খুবই সম্ভব যে access_type আপনার সেট করা একমাত্র কীওয়ার্ড আর্গুমেন্ট হবে না, যেমনটি নিচের উদাহরণে দেখানো হয়েছে।

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    ব্যবহারকারী অনুরোধ করা স্কোপে অফলাইন অ্যাক্সেস মঞ্জুর করার পরে, ব্যবহারকারী অফলাইনে থাকাকালীন আপনি ব্যবহারকারীর হয়ে Google API অ্যাক্সেস করতে API ক্লায়েন্ট ব্যবহার করা চালিয়ে যেতে পারেন। ক্লায়েন্ট অবজেক্ট প্রয়োজন মতো অ্যাক্সেস টোকেন রিফ্রেশ করবে।

    Ruby

    আপনার অ্যাপ্লিকেশনের Google API-তে অফলাইন অ্যাক্সেসের প্রয়োজন হলে, API ক্লায়েন্টের অ্যাক্সেস offlineটাইপ সেট করুন:

    auth_client.update!(
      :additional_parameters => {"access_type" => "offline"}
    )

    কোনও ব্যবহারকারী অনুরোধ করা স্কোপে অফলাইন অ্যাক্সেস দেওয়ার পরে, ব্যবহারকারী অফলাইনে থাকলেও আপনি API ক্লায়েন্ট ব্যবহার করে তার হয়ে Google API অ্যাক্সেস করা চালিয়ে যেতে পারবেন। ক্লায়েন্ট অবজেক্ট প্রয়োজন অনুযায়ী অ্যাক্সেস টোকেন রিফ্রেশ করবে।

    Node.js

    আপনার অ্যাপ্লিকেশনের যদি Google API-তে অফলাইন অ্যাক্সেসের প্রয়োজন হয়, তাহলে API ক্লায়েন্টের অ্যাক্সেসের ধরন offline-এ সেট করুন:

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });

    কোনও ব্যবহারকারী অনুরোধ করা স্কোপে অফলাইন অ্যাক্সেস দেওয়ার পরে, ব্যবহারকারী অফলাইনে থাকলেও আপনি API ক্লায়েন্ট ব্যবহার করে তার হয়ে Google API অ্যাক্সেস করা চালিয়ে যেতে পারবেন। ক্লায়েন্ট অবজেক্ট প্রয়োজন মতো অ্যাক্সেস টোকেন রিফ্রেশ করবে।

    অ্যাক্সেস টোকেনের মেয়াদ শেষ হয়ে যায়। এই লাইব্রেরি অটোমেটিক রিফ্রেশ টোকেন ব্যবহার করে নতুন অ্যাক্সেস টোকেন পাবে, যদি এটি মেয়াদ শেষ হওয়ার কাছাকাছি থাকে। সবচেয়ে সাম্প্রতিক টোকেন সবসময় স্টোর করার সহজ উপায় হল টোকেন ইভেন্ট ব্যবহার করা:

    oauth2Client.on('tokens', (tokens) => {
      if (tokens.refresh_token) {
        // store the refresh_token in your secure persistent database
        console.log(tokens.refresh_token);
      }
      console.log(tokens.access_token);
    });

    এই টোকেন ইভেন্ট শুধুমাত্র প্রথমবার অনুমোদন করার সময় ঘটে এবং রিফ্রেশ টোকেন পাওয়ার জন্য generateAuthUrl মেথড কল করার সময় আপনার access_type offline হিসেবে সেট করা থাকতে হবে। আপনি যদি রিফ্রেশ টোকেন পাওয়ার জন্য উপযুক্ত সীমাবদ্ধতা সেট না করেই আপনার অ্যাপকে প্রয়োজনীয় অনুমতি দিয়ে থাকেন, তাহলে আপনাকে একটি নতুন রিফ্রেশ টোকেন পেতে অ্যাপ্লিকেশনটি আবার অনুমোদন করতে হবে।

    পরে refresh_token সেট করতে, আপনি setCredentials পদ্ধতি ব্যবহার করতে পারেন:

    oauth2Client.setCredentials({
      refresh_token: `STORED_REFRESH_TOKEN`
    });

    ক্লায়েন্টের কাছে রিফ্রেশ টোকেন থাকলে, API-তে পরবর্তী কলের সময় অ্যাক্সেস টোকেন অটোমেটিক অ্যাকোয়ার ও রিফ্রেশ করা হবে।

    HTTP/REST

    অ্যাক্সেস টোকেন রিফ্রেশ করতে, আপনার অ্যাপ্লিকেশন Google-এর অনুমোদনের সার্ভারে (https://oauth2.googleapis.com/token) একটি HTTPS POST অনুরোধ পাঠায়, যার অনুরোধের বডিতে নিম্নলিখিত প্যারামিটার থাকে:

    নাম ভ্যালু
    client_id API কনসোল থেকে পাওয়া ক্লায়েন্ট আইডি।
    client_secret ঐচ্ছিক

    API কনসোল থেকে পাওয়া ক্লায়েন্ট সিক্রেট।

    grant_type OAuth 2.0 স্পেসিফিকেশনে যেমন বলা হয়েছে, এই ফিল্ডের ভ্যালু refresh_token হিসেবে সেট করতে হবে।
    refresh_token অথরাইজেশন কোড এক্সচেঞ্জ থেকে রিফ্রেশ টোকেন ফেরত এসেছে।

    DPoP-এর ব্যবহার ঐচ্ছিক হলেও, আরও বেশি নিরাপত্তার জন্য এটি ব্যবহার করার সাজেশন দেওয়া হয়। রিফ্রেশ টোকেনের সাথে DPoP ব্যবহার করতে, আপনার অ্যাপ্লিকেশনকে টোকেন এন্ডপয়েন্টে করা প্রতিটি অনুরোধের জন্য একটি নতুন, অনন্য DPoP প্রুফ JWT তৈরি করতে হবে। প্রাথমিক অথরাইজেশন কোড আদান-প্রদানের সময় যে প্রাইভেট কী ব্যবহার করা হয়েছিল, এই প্রমাণে সেই একই প্রাইভেট কী দিয়ে সাইন করতে হবে। আপনার অ্যাপ্লিকেশন HTTP অনুরোধ হেডার হিসেবে প্রমাণ যোগ করে।

    শিরোনাম প্রয়োজনীয় বিবরণ
    DPoP ঐচ্ছিক DPoP প্রমাণ হল একটি JWT যা প্রাইভেট কীয়ের মালিকানা প্রমাণ করে। এটি একটি হেডার, কোনও প্যারামিটার নয়। প্রদান করা হলে, ফিরে আসা টোকেন এই কী-এর সাথে আবদ্ধ থাকে। প্রতিটি অনুরোধের জন্য একটি নতুন, অনন্য প্রমাণ তৈরি করতে হবে এবং এতে অবশ্যই htm (HTTP পদ্ধতি) এবং htu (HTTP URI) দাবি অন্তর্ভুক্ত থাকতে হবে যা অনুরোধের সাথে মেলে।

    নিম্নলিখিত স্নিপেট একটি নমুনা অনুরোধ দেখায়:

    POST /token HTTP/1.1
    Host: oauth2.googleapis.com
    Content-Type: application/x-www-form-urlencoded
    DPoP: DPOP_PROOF_JWT
    
    client_id=your_client_id&
    refresh_token=refresh_token&
    grant_type=refresh_token

    রিফ্রেশ টোকেনের সাথে DPoP ব্যবহার করতে, আপনাকে অবশ্যই অনুরোধের জন্য একটি নতুন, অনন্য DPoP প্রমাণ JWT তৈরি করতে হবে। কী পেয়ার জেনারেট করা ও JWT তৈরি করার বিষয়ে ধাপে ধাপে নির্দেশাবলীর জন্য DPoP প্রমাণ তৈরি করা লিঙ্ক দেখুন।

    সফল এক্সচেঞ্জ হলে, নতুন অ্যাক্সেস টোকেন সহ একটি 200 OK উত্তর দেখানো হয়। DPoP ব্যবহার করা হলে, token_type হল Bearer। সফল উত্তর থেকে বোঝা যায় যে রিফ্রেশ টোকেনের জন্য DPoP প্রমাণ গ্রহণ করা হয়েছে। Google উত্তরে একটি নতুন DPoP-Nonce HTTP হেডারও পাঠাতে পারে; যদি পাঠানো হয়, তাহলে আপনার ক্লায়েন্টকে অবশ্যই এই ননস ক্যাশে করতে হবে এবং পরবর্তী অনুরোধে DPoP প্রমাণের nonce দাবিতে এটি অন্তর্ভুক্ত করতে হবে।

    DPoP হেডার না থাকলে, ভুল থাকলে বা ভুল কী ব্যবহার করলে এক্সচেঞ্জ সম্পূর্ণ করা যায় না। নির্দিষ্ট DPoP ত্রুটি কোড এবং ননস ম্যানেজ করা সম্পর্কে বিশদ বিবরণের জন্য, ব্যর্থ এক্সচেঞ্জ দেখুন।

    DPoP ব্যবহার করা হলে, নিম্নলিখিত স্নিপেটে সফল উত্তরের হেডার ও বডির একটি নমুনা দেখানো হয়েছে:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI
    
    {
      "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
      "expires_in": 3920,
      "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
      "token_type": "Bearer"
    }

    মনে রাখবেন, ইস্যু করা রিফ্রেশ টোকেনের সংখ্যার উপর সীমা আছে; ক্লায়েন্ট/ব্যবহারকারীর কম্বিনেশন প্রতি একটি সীমা এবং সমস্ত ক্লায়েন্ট জুড়ে ব্যবহারকারী প্রতি আরেকটি সীমা। আপনাকে দীর্ঘমেয়াদী স্টোরেজে রিফ্রেশ টোকেন সেভ করতে হবে এবং সেগুলি বৈধ থাকা পর্যন্ত ব্যবহার করা চালিয়ে যেতে হবে। আপনার অ্যাপ্লিকেশন অনেক বেশি রিফ্রেশ টোকেনের অনুরোধ করলে, এটি এই সীমার মধ্যে চলে যেতে পারে, সেক্ষেত্রে পুরনো রিফ্রেশ টোকেন কাজ করা বন্ধ করে দেবে।

    টোকেন প্রত্যাহার

    কিছু ক্ষেত্রে, কোনও ব্যবহারকারী কোনও অ্যাপ্লিকেশনকে দেওয়া অ্যাক্সেস প্রত্যাহার করতে চাইতে পারেন। ব্যবহারকারী অ্যাকাউন্ট সেটিংস-এ গিয়ে অ্যাক্সেস প্রত্যাহার করতে পারবেন। আরও তথ্যের জন্য আপনার অ্যাকাউন্টে অ্যাক্সেস আছে এমন থার্ড-পার্টি সাইট ও অ্যাপের সাইট বা অ্যাপ অ্যাক্সেস সরান সহায়তা ডকুমেন্ট দেখুন।

    এছাড়াও, কোনও অ্যাপ্লিকেশনকে দেওয়া অ্যাক্সেস প্রোগ্রাম্যাটিক্যালি প্রত্যাহার করা সম্ভব। প্রোগ্রাম্যাটিক প্রত্যাহার সেইসব ক্ষেত্রে গুরুত্বপূর্ণ যেখানে কোনও ব্যবহারকারী আনসাবস্ক্রাইব করেন, কোনও অ্যাপ্লিকেশন সরিয়ে দেন অথবা কোনও অ্যাপের জন্য প্রয়োজনীয় API রিসোর্স উল্লেখযোগ্যভাবে পরিবর্তিত হয়। অন্যভাবে বলতে গেলে, অ্যাপ্লিকেশনকে আগে দেওয়া অনুমতি সরিয়ে দেওয়া হয়েছে কিনা তা নিশ্চিত করতে, সরানোর প্রসেসের অংশ হিসেবে API অনুরোধ অন্তর্ভুক্ত থাকতে পারে।

    PHP

    প্রোগ্রাম্যাটিক্যালি টোকেন তুলে নিতে, revokeToken() কল করুন:

    $client->revokeToken();

    Python

    প্রোগ্রাম্যাটিক্যালি কোনও টোকেন তুলে নিতে, https://oauth2.googleapis.com/revoke-এ অনুরোধ করুন যাতে প্যারামিটার হিসেবে টোকেন অন্তর্ভুক্ত থাকে এবং Content-Type হেডার সেট করে:

    requests.post('https://oauth2.googleapis.com/revoke',
        params={'token': credentials.token},
        headers = {'content-type': 'application/x-www-form-urlencoded'})

    Ruby

    প্রোগ্র্যামাটিক্যালি টোকেন তুলে নিতে, oauth2.revoke এন্ডপয়েন্টে HTTP অনুরোধ করুন:

    uri = URI('https://oauth2.googleapis.com/revoke')
    response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)

    টোকেনটি অ্যাক্সেস টোকেন বা রিফ্রেশ টোকেন হতে পারে। টোকেনটি অ্যাক্সেস টোকেন হলে এবং সেটির অনুরূপ রিফ্রেশ টোকেন থাকলে, রিফ্রেশ টোকেনও প্রত্যাহার করা হবে।

    প্রত্যাহার করার অনুরোধ সফলভাবে প্রসেস করা হলে, রেসপন্সের স্ট্যাটাস কোড হবে 200। সমস্যার ক্ষেত্রে, স্ট্যাটাস কোড 400-এর সাথে একটি সমস্যা কোড ফেরত পাঠানো হয়।

    Node.js

    প্রোগ্র্যামাটিক পদ্ধতিতে টোকেন প্রত্যাহার করতে, /revoke এন্ডপয়েন্টে একটি HTTPS POST অনুরোধ করুন:

    const https = require('https');
    
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;
    
    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };
    
    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });
    
    postReq.on('error', error => {
      console.log(error)
    });
    
    // Post the request with data
    postReq.write(postData);
    postReq.end();

    টোকেন প্যারামিটারটি অ্যাক্সেস টোকেন বা রিফ্রেশ টোকেন হতে পারে। টোকেনটি অ্যাক্সেস টোকেন হলে এবং সেটির অনুরূপ রিফ্রেশ টোকেন থাকলে, রিফ্রেশ টোকেনও প্রত্যাহার করা হবে।

    প্রত্যাহার করার অনুরোধ সফলভাবে প্রসেস করা হলে, রেসপন্সের স্ট্যাটাস কোড হবে 200। সমস্যার ক্ষেত্রে, স্ট্যাটাস কোড 400-এর সাথে একটি সমস্যা কোড ফেরত পাঠানো হয়।

    HTTP/REST

    প্রোগ্রামাটিক উপায়ে টোকেন প্রত্যাহার করতে, আপনার অ্যাপ্লিকেশন https://oauth2.googleapis.com/revoke-এ একটি অনুরোধ করে এবং টোকেনটিকে প্যারামিটার হিসেবে অন্তর্ভুক্ত করে:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    টোকেনটি অ্যাক্সেস টোকেন বা রিফ্রেশ টোকেন হতে পারে। টোকেনটি যদি অ্যাক্সেস টোকেন হয় এবং সেটির সাথে সংশ্লিষ্ট রিফ্রেশ টোকেন থাকে, তাহলে রিফ্রেশ টোকেনটিও বাতিল করা হবে।

    প্রত্যাহার করার অনুরোধ সফলভাবে প্রসেস করা হলে, উত্তরের HTTP স্ট্যাটাস কোড হল 200। সমস্যার ক্ষেত্রে, HTTP স্ট্যাটাস কোড 400-এর সাথে একটি ত্রুটি কোড পাঠানো হয়।

    সময়-ভিত্তিক অ্যাক্সেস

    সময়-ভিত্তিক অ্যাক্সেস কোনও ব্যবহারকারীকে সীমিত সময়ের জন্য আপনার অ্যাপকে তার ডেটা অ্যাক্সেস করার অনুমতি দিতে দেয় যাতে কোনও অ্যাকশন সম্পূর্ণ করা যায়। সম্মতি ফ্লো চলাকালীন বেছে নেওয়া Google প্রোডাক্টে সময়-ভিত্তিক অ্যাক্সেস উপলভ্য, যা ব্যবহারকারীদের সীমিত সময়ের জন্য অ্যাক্সেস দেওয়ার বিকল্প প্রদান করে। এর একটি উদাহরণ হল Data Portability API যা ডেটার এককালীন ট্রান্সফার করার সুবিধা দেয়।

    কোনও ব্যবহারকারী আপনার অ্যাপ্লিকেশনকে সময়-ভিত্তিক অ্যাক্সেস দিলে, নির্দিষ্ট সময়সীমা শেষ হওয়ার পরে রিফ্রেশ টোকেনের মেয়াদ শেষ হয়ে যাবে। মনে রাখবেন, নির্দিষ্ট পরিস্থিতিতে রিফ্রেশ টোকেন আগেই বাতিল হয়ে যেতে পারে; বিস্তারিত জানতে এইসব পরিস্থিতি দেখুন। যাচাইকরণ কোড এক্সচেঞ্জ রেসপন্সে ফেরত আসা refresh_token_expires_in ফিল্ডটি এই ধরনের ক্ষেত্রে রিফ্রেশ টোকেনের মেয়াদ শেষ না হওয়া পর্যন্ত বাকি সময়কে দেখায়।

    ক্রস-অ্যাকাউন্ট সুরক্ষা প্রয়োগ করা

    আপনার ব্যবহারকারীদের অ্যাকাউন্ট সুরক্ষিত রাখতে আপনাকে একটি অতিরিক্ত পদক্ষেপ নিতে হবে, সেটি হল Google-এর ক্রস-অ্যাকাউন্ট সুরক্ষা পরিষেবা ব্যবহার করে ক্রস-অ্যাকাউন্ট সুরক্ষা প্রয়োগ করা। এই পরিষেবা আপনাকে নিরাপত্তা ইভেন্ট সংক্রান্ত বিজ্ঞপ্তি সাবস্ক্রাইব করতে দেয়, যা ব্যবহারকারীর অ্যাকাউন্টে হওয়া বড় ধরনের পরিবর্তন সম্পর্কে আপনার অ্যাপ্লিকেশনকে তথ্য প্রদান করে। আপনি তারপরে সেই তথ্য ব্যবহার করে অ্যাকশন নিতে পারবেন, এটি নির্ভর করে আপনি কীভাবে ইভেন্টে প্রতিক্রিয়া জানাতে চান তার উপর।

    Google-এর ক্রস-অ্যাকাউন্ট সুরক্ষা পরিষেবা আপনার অ্যাপে যে ধরনের ইভেন্ট পাঠায় তার কিছু উদাহরণ হল:

    • https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
    • https://schemas.openid.net/secevent/oauth/event-type/token-revoked
    • https://schemas.openid.net/secevent/risc/event-type/account-disabled

    ক্রস-অ্যাকাউন্ট সুরক্ষা কীভাবে প্রয়োগ করতে হয় এবং উপলভ্য ইভেন্টের সম্পূর্ণ তালিকা পেতে ক্রস-অ্যাকাউন্ট সুরক্ষা পৃষ্ঠার মাধ্যমে ব্যবহারকারীর অ্যাকাউন্ট সুরক্ষিত করুন লিঙ্ক দেখুন।