Google متعهد به پیشبرد عدالت نژادی برای جوامع سیاهپوست است. ببینید چگونه.

استفاده از OAuth 2.0 برای برنامه های سرور به سرور

سیستم Google OAuth 2.0 از تعاملات سرور به سرور مانند تعاملات بین یک برنامه وب و یک سرویس Google پشتیبانی می کند. برای این سناریو شما به یک حساب سرویس نیاز دارید ، که حسابی است که به جای اینکه به یک کاربر نهایی شخصی متعلق به برنامه شما باشد. برنامه شما از طرف حساب سرویس با Google API تماس می گیرد ، بنابراین کاربران مستقیماً درگیر آن نیستند. این سناریو را گاهی اوقات "OAuth دو پا" یا "2LO" می نامند. (اصطلاح مربوط به "OAuth سه پایه" به سناریوهایی گفته می شود که در آن برنامه شما از طرف کاربران نهایی با Google API تماس می گیرد و در برخی مواقع رضایت کاربر نیز در آنها لازم است.)

به طور معمول ، هنگامی که برنامه از Google API برای کار با داده های خود و نه داده کاربر استفاده می کند ، از یک حساب سرویس استفاده می کند. به عنوان مثال ، برنامه ای که برای ماندگاری داده از Google Cloud Datastore استفاده می کند ، برای تأیید اعتبار تماس های خود با API Google Cloud Datastore از یک حساب سرویس استفاده می کند.

سرپرستان دامنه Google Workspace همچنین می توانند در سراسر دامنه به حساب های خدمات اجازه دسترسی به داده های کاربر را از طرف کاربران در دامنه دهند.

این سند توضیح می دهد که چگونه یک برنامه می تواند جریان OAuth 2.0 سرور به سرور را با استفاده از کتابخانه مشتری Google APIs (توصیه می شود) یا HTTP کامل کند.

بررسی اجمالی

برای پشتیبانی از تعاملات سرور به سرور ، ابتدا یک حساب سرویس برای پروژه خود در API Console ایجاد کنید. اگر می خواهید در حساب Google Workspace خود به داده های کاربر برای کاربران دسترسی پیدا کنید ، دسترسی گسترده دامنه را به حساب سرویس اختصاص دهید.

سپس ، برنامه شما آماده می شود تا با استفاده از اعتبارنامه حساب سرویس برای درخواست رمز دسترسی از سرور خودکار OAuth 2.0 ، تماسهای API مجاز برقرار کند.

سرانجام ، برنامه شما می تواند از رمز دسترسی برای تماس با API های Google استفاده کند.

ایجاد حساب کاربری

اطلاعات کاربری یک حساب سرویس شامل یک آدرس ایمیل تولید شده است که منحصر به فرد و حداقل یک جفت کلید عمومی / خصوصی است. اگر تفویض دامنه فعال باشد ، شناسه مشتری نیز بخشی از اعتبار حساب سرویس است.

اگر برنامه شما در Google App Engine اجرا شود ، هنگام ایجاد پروژه خود ، یک حساب سرویس به طور خودکار تنظیم می شود.

اگر برنامه شما روی Google Compute Engine اجرا شود ، هنگام ایجاد پروژه خود ، یک حساب سرویس نیز به طور خودکار تنظیم می شود ، اما باید هنگام ایجاد نمونه Google Compute Engine ، محدوده هایی را که برنامه شما به آنها نیاز دارد ، تعیین کنید. برای اطلاعات بیشتر ، به تهیه نمونه برای استفاده از حساب های سرویس مراجعه کنید .

اگر برنامه شما در Google App Engine یا Google Compute Engine اجرا نمی شود ، باید این مدارک را در Google API Console بدست آورید. برای تولید اعتبار نامه حساب سرویس یا مشاهده اعتبار عمومی که قبلاً ایجاد کرده اید ، موارد زیر را انجام دهید:

  1. Service accounts page را باز کنید.
  2. If prompted, select a project, or create a new one.
  3. روی ایجاد حساب کاربری کلیک .
  4. در زیر جزئیات حساب سرویس ، نام ، شناسه و توضیحی را برای حساب خدمات تایپ کنید ، سپس روی ایجاد کلیک کنید.
  5. اختیاری: تحت مجوزهای حساب خدمات خدمات ، نقشهای IAM را برای اعطای به حساب سرویس انتخاب کنید ، سپس روی ادامه کلیک کنید.
  6. اختیاری: در زیر دسترسی کاربران Grant به این حساب خدمات ، کاربران یا گروه هایی که مجاز به استفاده و مدیریت حساب سرویس هستند را اضافه کنید.
  7. روی کلید ایجاد کلیک کرده و سپس روی ایجاد کلیک کنید.

جفت کلید عمومی عمومی / خصوصی شما در دستگاه شما تولید و بارگیری می شود. این تنها نسخه اصلی کلید خصوصی است. شما وظیفه ذخیره ایمن آن را بر عهده دارید. اگر این جفت کلید را گم کنید ، باید یک مورد جدید تولید کنید.

اگر لازم است مجوز دامنه G Suite را به حساب خدمات اختصاص دهید ، روی آدرس ایمیل حساب کاربری که ایجاد کرده اید کلیک کنید ، سپس مقدار را از کادر Unique ID کپی کنید.

برای واگذاری اختیار به حساب سرویس ، از مقداری که کپی کرده اید به عنوان شناسه مشتری استفاده کنید.

برای مشاهده آدرس ایمیل ، اثر انگشت کلید عمومی و سایر اطلاعات یا ایجاد زوج کلید عمومی / خصوصی خصوصی در هر زمان می توانید به شماره API Console بازگردید . برای جزئیات بیشتر در مورد اعتبار حساب سرویس در API Console ، به حساب های سرویس در پرونده راهنمای API Console مراجعه کنید.

آدرس ایمیل حساب سرویس را یادداشت کنید و پرونده کلید خصوصی حساب سرویس را در مکانی که برای برنامه شما قابل دسترسی است ذخیره کنید. برنامه شما برای برقراری تماسهای API مجاز به آنها نیاز دارد.

تفویض اختیارات دامنه به حساب سرویس

اگر حساب Google Workspace دارید ، یک مدیر سازمان می تواند به یک برنامه کاربردی اجازه دسترسی به داده های کاربر را از طرف کاربران در دامنه Google Workspace دهد. به عنوان مثال ، برنامه ای که از Google Calendar API برای افزودن رویدادها به تقویم های همه کاربران در یک دامنه Google Workspace استفاده می کند ، از یک حساب سرویس برای دسترسی به Google Calendar API از طرف کاربران استفاده می کند. مجوز دادن یک حساب سرویس برای دسترسی به داده ها از طرف کاربران در یک دامنه ، گاهی اوقات به عنوان "تفویض اختیار دامنه" به یک حساب سرویس شناخته می شود.

برای تفویض اختیار دامنه به یک حساب سرویس ، ابتدا تفویض دامنه را برای یک حساب سرویس موجود در Service accounts page فعال کنید یا یک حساب سرویس جدید با واگذاری نمایه دامنه ایجاد کنید .

سپس ، یک مدیر عالی از دامنه Google Workspace باید مراحل زیر را انجام دهد:

  1. از دامنه Google فضای کاری خود را کنسول مدیریت ، به منوی اصلی بروید > امنیت> کنترل API.
  2. در بخش نمایندگی دامنه گسترده دامنه ، مدیریت دامنه نمایندگی گسترده را انتخاب کنید .
  3. روی افزودن جدید کلیک کنید.
  4. در زمینه مشتری ID، ID مشتری حساب خدمات را وارد کنید. شناسه مشتری حساب خدمات خود را می توانید در شماره Service accounts page پیدا کنید.
  5. در قسمت OAuth (محدودیت ویرگول) ، لیست محدوده هایی را که باید به برنامه شما اجازه دسترسی داده شود وارد کنید. به عنوان مثال ، اگر برنامه شما به دسترسی کامل دامنه به Google Drive API و Google Calendar API نیاز دارد ، وارد کنید: https://www.googleapis.com/auth/drive ، https://www.googleapis.com/auth / تقویم
  6. مجاز کردن را کلیک کنید.

برنامه شما اکنون این اختیار را دارد که به عنوان کاربر در دامنه شما (برای "جعل هویت" از کاربران) با API تماس برقرار کند. وقتی برای برقراری تماسهای API مجاز آماده می شوید ، کاربر را برای جعل هویت مشخص می کنید.

در حال آماده سازی برای برقراری تماس API مجاز

جاوا

بعد از اینکه آدرس ایمیل و کلید خصوصی مشتری را از API Console بدست آوردید ، از Google APIs Client Library برای جاوا برای ایجاد یک شی GoogleCredential از اعتبار حساب کاربری و دامنه هایی که برنامه شما نیاز به دسترسی دارد استفاده کنید. مثلا:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));

اگر در حال ساخت برنامه در Google Cloud Platform هستید ، می توانید به جای آن از اعتبارنامه پیش فرض برنامه استفاده کنید که این امر می تواند روند کار را ساده کند.

اختیارات دامنه گسترده را تفویض کنید

اگر دسترسی گسترده دامنه خود را به حساب سرویس اختصاص داده اید و می خواهید یک حساب کاربری خود را جعل کنید ، آدرس ایمیل حساب کاربری خود را با روش createDelegated از شی createDelegated GoogleCredential مشخص کنید. مثلا:

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("user@example.com");

برای فراخوانی API های Google در برنامه خود از شی GoogleCredential استفاده کنید.

پایتون

پس از دریافت آدرس ایمیل مشتری و کلید خصوصی از API Console ، برای تکمیل مراحل زیر از کتابخانه مشتری APIs Google برای Python استفاده کنید :

  1. از Credentials حساب کاربری و محدوده هایی که برنامه شما به آنها دسترسی دارد ، یک شی Credentials ایجاد کنید. به عنوان مثال:
    from google.oauth2 import service_account
    
    SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
    SERVICE_ACCOUNT_FILE = '/path/to/service.json'
    
    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    اگر در حال ساخت برنامه در Google Cloud Platform هستید ، می توانید به جای آن از اعتبارنامه پیش فرض برنامه استفاده کنید که این امر می تواند روند کار را ساده کند.

  2. اختیارات دامنه گسترده را تفویض کنید

    اگر دسترسی گسترده دامنه خود را به حساب سرویس اختصاص داده اید و می خواهید یک حساب کاربری را جعل کنید ، از روش with_subject یک شی موجود ServiceAccountCredentials استفاده کنید. مثلا:

    delegated_credentials = credentials.with_subject('user@example.org')

برای فراخوانی Google API ها در برنامه خود از شی Credentials استفاده کنید.

HTTP / REST

پس از دریافت شناسه مشتری و کلید خصوصی از API Console ، برنامه شما باید مراحل زیر را انجام دهد:

  1. یک JSON Web Token (JWT ، تلفظ شده ، "jot") ایجاد کنید که شامل یک سرصفحه ، مجموعه ادعا و امضا باشد.
  2. از سرور مجوز Google OAuth 2.0 درخواست رمز دسترسی کنید.
  3. پاسخ JSON را که سرور مجوز برمی گرداند مدیریت کنید.

بخشهایی که در ادامه می خوانید نحوه تکمیل این مراحل را شرح می دهد.

اگر پاسخ شامل رمز دسترسی است ، می توانید از رمز دسترسی برای تماس با API Google استفاده کنید . (اگر پاسخ شامل رمز دسترسی نباشد ، ممکن است درخواست JWT و رمز شما به درستی تشکیل نشده باشد یا حساب سرویس اجازه دسترسی به محدوده های درخواستی را نداشته باشد.)

وقتی رمز دسترسی منقضی شد ، برنامه شما JWT دیگری ایجاد می کند ، آن را امضا می کند و رمز دسترسی دیگری را درخواست می کند.

برنامه سرور شما برای درخواست رمز از سرور مجوز Google از JWT استفاده می کند ، سپس برای فراخوانی نقطه پایانی Google API از رمز استفاده می کند. هیچ کاربر نهایی درگیر نیست.

در ادامه این بخش مشخصات ایجاد JWT ، امضای JWT ، تشکیل درخواست رمز دسترسی و مدیریت پاسخ توضیح داده شده است.

ایجاد JWT

JWT از سه قسمت تشکیل شده است: یک عنوان ، یک مجموعه ادعا و یک امضا. مجموعه سرصفحه و ادعا اشیا J JSON هستند. این اشیا J JSON به صورت بایت سریال UTF-8 تنظیم شده و سپس با استفاده از رمزگذاری Base64url کدگذاری می شوند. این رمزگذاری باعث انعطاف پذیری در برابر تغییرات رمزگذاری شده به دلیل انجام عملیات رمزگذاری مکرر می شود. عنوان ، مجموعه ادعا و امضا همراه با کاراکتر دوره ( . ) بهم پیوسته اند.

JWT به شرح زیر تشکیل شده است:

{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}

رشته پایه برای امضا به شرح زیر است:

{Base64url encoded header}.{Base64url encoded claim set}
تشکیل سرآیند JWT

سربرگ از دو قسمت تشکیل شده است که الگوریتم امضای و قالب ادعا را نشان می دهد. هر دو قسمت اجباری است و هر فیلد فقط یک مقدار دارد. با معرفی الگوریتم ها و قالب های اضافی ، این عنوان به همین ترتیب تغییر خواهد کرد.

حساب های سرویس به الگوریتم RSA SHA-256 و قالب رمز JWT متکی هستند. در نتیجه ، نمایش سرصفحه JSON به شرح زیر است:

{"alg":"RS256","typ":"JWT"}

نمایندگی Base64url به شرح زیر است:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
تشکیل مجموعه ادعای JWT

مجموعه ادعای JWT شامل اطلاعاتی درباره JWT ، از جمله مجوزهای درخواستی (محدوده ها) ، هدف نشانه ، صادر کننده ، زمان صدور رمز و طول عمر رمز است. بیشتر زمینه ها اجباری است. مانند عنوان JWT ، مجموعه ادعای JWT نیز یک شی J JSON است و در محاسبه امضا استفاده می شود.

ادعاهای مورد نیاز

ادعاهای مورد نیاز در مجموعه ادعاهای JWT در زیر نشان داده شده است. آنها ممکن است به ترتیب در مجموعه ادعاها ظاهر شوند.

نام شرح
iss آدرس ایمیل حساب سرویس.
scope لیستی از مجوزهایی که برنامه درخواست می کند.
aud توصیف کننده هدف مورد نظر برای ادعا. هنگام ایجاد درخواست رمز دسترسی ، این مقدار همیشه https://oauth2.googleapis.com/token .
exp زمان انقضا ادعا ، مشخص شده به عنوان ثانیه از ساعت 00:00:00 UTC ، 1 ژانویه 1970. این مقدار حداکثر 1 ساعت پس از زمان صادر شده دارد.
iat زمان صدور ادعا ، به عنوان ثانیه از ساعت 00:00:00 UTC تنظیم شده است ، 1 ژانویه 1970.

نمایش JSON از قسمتهای مورد نیاز در یک مجموعه ادعای JWT در زیر نشان داده شده است:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/devstorage.read_only",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
ادعاهای اضافی

در برخی از موارد سازمانی ، یک برنامه کاربردی می تواند از تفویض دامنه برای فعالیت به نمایندگی از یک کاربر خاص در یک سازمان استفاده کند. اجازه انجام این نوع جعل هویت باید قبل از جعل هویت یک کاربر از یک برنامه داده شود و معمولاً توسط یک مدیر فوق العاده اداره می شود. برای کسب اطلاعات بیشتر ، به کنترل دسترسی API با واگذاری دامنه مراجعه کنید .

برای به دست آوردن رمز دسترسی که به برنامه مجوز دسترسی به منبع را اعطا می کند ، آدرس ایمیل کاربر را در ادعای JWT تنظیم کنید که به عنوان مقدار قسمت sub است.

نام شرح
sub آدرس ایمیل کاربری که برنامه درخواست دسترسی تفویض شده برای آن را دارد.

اگر برنامه ای مجوز جعل هویت کاربر را نداشته باشد ، پاسخ به درخواست رمز دسترسی که شامل قسمت sub است یک خطا خواهد بود.

نمونه ای از مجموعه ادعاهای JWT که شامل قسمت sub است در زیر نشان داده شده است:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "some.user@example.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
رمزگذاری مجموعه ادعاهای JWT

مانند عنوان JWT ، مجموعه ادعاهای JWT نیز باید به صورت رمزگذاری شده در UTF-8 و Base64url امن باشد. در زیر نمونه ای از نمایندگی JSON از مجموعه ادعاهای JWT آورده شده است:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
محاسبه امضا

JSON Web Signature (JWS) مشخصاتی است که مکانیک تولید امضا را برای JWT راهنمایی می کند. ورودی برای امضا آرایه بایت محتوای زیر است:

{Base64url encoded header}.{Base64url encoded claim set}

هنگام محاسبه امضا باید از الگوریتم امضا در هدر JWT استفاده شود. تنها الگوریتم امضای پشتیبانی شده توسط سرور مجوز Google OAuth 2.0 RSA با استفاده از الگوریتم هش SHA-256 است. این را به عنوان بیان RS256 در alg درست در هدر JWT است.

نمایش UTF-8 ورودی را با استفاده از SHA256withRSA (همچنین به عنوان RSASSA-PKCS1-V1_5-SIGN با عملکرد هش SHA-256 شناخته می شود) با کلید خصوصی به دست آمده از Google API Console امضا کنید. خروجی یک آرایه بایت خواهد بود.

سپس امضا باید Base64url رمزگذاری شود. عنوان ، مجموعه ادعا و امضا همراه با کاراکتر دوره ( . ) بهم پیوسته اند. نتیجه JWT است. این باید به صورت زیر باشد (شکافهای خط برای شفافیت اضافه می شوند):

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

در زیر مثالی از JWT قبل از رمزگذاری Base64url آورده شده است:

{"alg":"RS256","typ":"JWT"}.
{
"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://oauth2.googleapis.com/token",
"exp":1328554385,
"iat":1328550785
}.
[signature bytes]

در زیر نمونه ای از JWT امضا شده و آماده انتقال است:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ

ایجاد درخواست رمز دسترسی

پس از ایجاد JWT امضا شده ، یک برنامه کاربردی می تواند از آن برای درخواست رمز دسترسی استفاده کند. این درخواست رمز دسترسی یک درخواست HTTPS POST و بدنه آن URL رمزگذاری شده است. URL در زیر نشان داده شده است:

https://oauth2.googleapis.com/token

پارامترهای زیر در درخواست HTTPS POST مورد نیاز است:

نام شرح
grant_type از رشته زیر ، در صورت لزوم با رمزگذاری URL استفاده کنید: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion JWT ، شامل امضا.

در زیر تخلیه خام درخواست HTTPS POST مورد استفاده در درخواست رمز دسترسی وجود دارد:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ

در زیر همان درخواست با استفاده از curl :

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU
' https://oauth2.googleapis.com/token

رسیدگی به پاسخ

اگر درخواست JWT و توکن دسترسی به درستی تشکیل شده باشد و حساب سرویس دارای اجازه انجام عملیات باشد ، پاسخ JSON از سرور مجوز دارای یک رمز دسترسی است. موارد زیر مثالی از پاسخ است:

{
  "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "scope": "https://www.googleapis.com/auth/prediction"
  "token_type": "Bearer",
  "expires_in": 3600
}

از نشانه های دسترسی می توان در پنجره مدت زمان مشخص شده با مقدار expires_in استفاده مجدد کرد.

تماس با API های Google

جاوا

با تکمیل مراحل زیر از شی GoogleCredential برای فراخوانی API های گوگل استفاده کنید:

  1. برای API یک شی سرویس ایجاد کنید که می خواهید با استفاده از شی GoogleCredential با آن تماس بگیرید. به عنوان مثال:
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. با استفاده از رابط کاربری ارائه شده توسط سرویس سرویس ، درخواست سرویس API را ارسال کنید. به عنوان مثال ، برای لیست موارد پایگاه داده Cloud SQL در پروژه جالب-مثال -123:
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

پایتون

با تکمیل مراحل زیر از شی Credentials استفاده کنید تا با API های Google تماس بگیرید:

  1. برای API یک شی سرویس ایجاد کنید که می خواهید با آن تماس بگیرید. شما با فراخوانی تابع build با نام و نسخه API و شی Credentials مجاز ، یک شی service سرویس aa ایجاد می کنید. به عنوان مثال ، برای تماس با نسخه 1beta3 از Cloud SQL Administration API:
    import googleapiclient.discovery
    
    sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
  2. با استفاده از رابط کاربری ارائه شده توسط سرویس سرویس ، درخواست سرویس API را ارسال کنید. به عنوان مثال ، برای لیست موارد پایگاه داده Cloud SQL در پروژه جالب-مثال -123:
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP / REST

بعد از اینکه برنامه شما رمز دسترسی به دست آورد ، در صورت اعطای محدوده (های) دسترسی مورد نیاز API ، می توانید از این رمز برای برقراری تماس با API Google از طرف یک حساب سرویس یا حساب کاربری استفاده کنید. برای این منظور ، رمز ورود را در یک درخواست به API با access_token پارامتر پرس و جو access_token یا مقدار Bearer سرصفحه HTTP Authorization . در صورت امکان ، سرآیند HTTP ترجیح داده می شود ، زیرا رشته های پرس و جو معمولاً در گزارش های سرور قابل مشاهده هستند. در اکثر موارد می توانید از کتابخانه سرویس گیرنده برای تنظیم تماس های خود با Google API استفاده کنید (به عنوان مثال ، هنگام تماس با API Drive Files ).

می توانید تمام API های Google را امتحان کنید و دامنه های آنها را در OAuth 2.0 Playground مشاهده کنید .

مثالهای HTTP GET

تماس با نقطه پایان drive.files (API فایلهای Drive) با استفاده از Authorization: Bearer عنوان HTTP Authorization: Bearer ممکن است به صورت زیر باشد. توجه داشته باشید که باید رمز دسترسی خود را مشخص کنید:

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

در اینجا فراخوانی همان API برای کاربر تأیید شده با استفاده از پارامتر رشته پرس و جو access_token دارد:

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

وقتی نشانه های دسترسی منقضی می شود

نشانه های دسترسی صادر شده توسط سرور مجوز Google OAuth 2.0 پس از مدت زمان ارائه شده توسط مقدار expires_in . وقتی نشانه دسترسی منقضی شد ، برنامه باید JWT دیگری ایجاد کند ، آن را امضا کرده و رمز دسترسی دیگری را درخواست کند.

کدهای خطای JWT

error error_description معنی نحوه حل و فصل
unauthorized_client Unauthorized client or scope in request. اگر می خواهید از واگذاری دامنه استفاده کنید ، حساب سرویس در کنسول Admin دامنه کاربر مجاز نیست.

اطمینان حاصل کنید که حساب سرویس در صفحه اعلان دامنه از کنسول مدیر برای کاربر در ادعای sub (قسمت) مجاز است.

اگرچه معمولاً چند دقیقه طول می کشد ، اما ممکن است حداکثر 24 ساعت طول بکشد تا مجوز برای همه کاربران در حساب Google شما منتشر شود.

unauthorized_client Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. حساب سرویس با استفاده از آدرس ایمیل مشتری به جای شناسه مشتری (عددی) در کنسول Admin مجاز شد. در صفحه نمایندگی دامنه در کنسول Admin ، سرویس گیرنده را بردارید و دوباره آن را با شناسه عددی اضافه کنید.
access_denied (هر ارزشی) اگر از نمایندگی دامنه استفاده می کنید ، یک یا چند دامنه درخواست شده در کنسول مدیر مجاز نیستند.

اطمینان حاصل کنید که حساب سرویس در صفحه اعلان دامنه از کنسول سرپرست برای کاربر در ادعای sub (قسمت) مجاز است و شامل تمام دامنه های درخواست شده در ادعای scope JWT شما می شود.

اگرچه معمولاً چند دقیقه طول می کشد ، اما ممکن است حداکثر 24 ساعت طول بکشد تا مجوز برای همه کاربران در حساب Google شما منتشر شود.

invalid_grant Not a valid email. کاربر وجود ندارد بررسی کنید آدرس ایمیل موجود در ادعای sub (قسمت) صحیح باشد.
invalid_grant

Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your 'iat' and 'exp' values and use a clock with skew to account for clock differences between systems.

معمولاً به این معنی است که زمان سیستم محلی صحیح نیست. همچنین می تواند اتفاق می افتد اگر exp ارزش بیش از 65 دقیقه در آینده از است iat ارزش، یا exp مقدار کمتر از است iat ارزش.

اطمینان حاصل کنید که ساعت روی سیستمی که JWT در آن تولید شده صحیح است. در صورت لزوم ، وقت خود را با Google NTP همگام سازی کنید.

invalid_grant Invalid JWT Signature.

ادعای JWT با یک کلید خصوصی امضا می شود که با حساب سرویس شناسایی شده توسط ایمیل مشتری مرتبط نیست.

متناوباً ، ادعای JWT ممکن است نادرست رمزگذاری شود - باید با Base64 رمزگذاری شود ، بدون خطوط جدید یا علائم برابر با پد.

مجموعه ادعاهای JWT را رمزگشایی کنید و تأیید کنید که کلید ادعای مربوط به حساب سرویس مرتبط است.

برای اطمینان از تولید صحیح JWT سعی کنید از کتابخانه OAuth ارائه شده توسط Google استفاده کنید.

invalid_scope Invalid OAuth scope or ID token audience provided. هیچ محدوده ای درخواست نشده است (لیست خالی محدوده ها) ، یا یکی از محدوده های درخواستی وجود ندارد (یعنی نامعتبر است).

اطمینان حاصل کنید که ادعای scope (فیلد) JWT پر شده است ، و دامنه هایی را که شامل آن است با دامنه های مستند API هایی که می خواهید استفاده کنید مقایسه کنید ، تا اطمینان حاصل کنید که خطا یا اشتباه تایپی وجود ندارد.

توجه داشته باشید که لیست scope ادعای scope باید با فاصله و نه با کاما از هم جدا شوند.

disabled_client The OAuth client was disabled. کلید استفاده شده برای امضای ادعای JWT غیرفعال است.

به آدرس Google API Console بروید و در بخش IAM & Admin> Accounts Service ، حساب سرویس را که حاوی "شناسه کلیدی" برای امضای ادعا است فعال کنید.

ضمیمه: مجوز حساب سرویس بدون OAuth

با استفاده از برخی از API های گوگل ، می توانید تماس های API مجاز را با استفاده از JWT امضا شده مستقیماً به عنوان رمز حامل برقرار کنید ، نه رمز دسترسی OAuth 2.0. وقتی این امکان وجود دارد ، می توانید قبل از برقراری تماس API از درخواست شبکه به سرور مجوز Google خودداری کنید.

اگر API ای که می خواهید با آن تماس بگیرید تعریف سرویس در مخزن Google APIs GitHub منتشر شده است ، می توانید به جای رمز ورود با استفاده از JWT تماس های مجاز API برقرار کنید. برای انجام این کار:

  1. همانطور که در بالا توضیح داده شد یک حساب سرویس ایجاد کنید . هنگام ایجاد حساب حتماً فایل JSON را که دریافت می کنید نگه دارید.
  2. با استفاده از هر کتابخانه استاندارد JWT ، مانند آنچه در jwt.io یافت می شود ، یک JWT با یک هدر و بار مناسب مانند مثال زیر ایجاد کنید:
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "123456-compute@developer.gserviceaccount.com",
      "sub": "123456-compute@developer.gserviceaccount.com",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • برای قسمت kid در عنوان ، شناسه کلید خصوصی حساب سرویس خود را مشخص کنید. این مقدار را می توانید در قسمت private_key_id فایل سرویس JSON حساب سرویس خود پیدا کنید.
    • برای قسمت های iss و sub ، آدرس ایمیل حساب سرویس خود را مشخص کنید. این مقدار را می توانید در قسمت client_email فایل سرویس JSON حساب سرویس خود پیدا کنید.
    • برای قسمت aud ، نقطه پایانی API را مشخص کنید. به عنوان مثال: https:// SERVICE .googleapis.com/ .
    • برای قسمت iat ، زمان فعلی Unix و برای قسمت exp ، زمان را دقیقاً 3600 ثانیه بعد ، که منقضی می شود JWT ، مشخص کنید.

با استفاده از کلید خصوصی موجود در پرونده JSON حساب سرویس خود ، JWT را با RSA-256 امضا کنید.

مثلا:

جاوا

با استفاده از google-api-java-client و java-jwt :

GoogleCredential credential =
        GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
String privateKeyId = credential.getServiceAccountPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("123456-compute@developer.gserviceaccount.com")
        .withSubject("123456-compute@developer.gserviceaccount.com")
        .withAudience("https://firestore.googleapis.com/")
        .withIssuedAt(new Date(now))
        .withExpiresAt(new Date(now + 3600 * 1000L))
        .sign(algorithm);
} catch ...

پایتون

با استفاده از PyJWT :

iat = time.time()
exp = iat + 3600
payload = {'iss': '123456-compute@developer.gserviceaccount.com',
           'sub': '123456-compute@developer.gserviceaccount.com',
           'aud': 'https://firestore.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers,
                       algorithm='RS256')
  1. با استفاده از JWT امضا شده به عنوان رمز حامل با API تماس بگیرید:
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com