OAuth 2.0

این سند OAuth 2.0، زمان استفاده از آن، نحوه به دست آوردن شناسه های سرویس گیرنده و نحوه استفاده از آن با Google API Client Library برای دات نت را توضیح می دهد.

پروتکل OAuth 2.0

OAuth 2.0 پروتکل مجوز استفاده شده توسط Google API است. شما باید با مطالعه لینک های زیر با پروتکل آشنا شوید:

به دست آوردن شناسه ها و اسرار مشتری

می‌توانید شناسه‌های مشتری و اسرار را در Google API Console دریافت کنید. انواع مختلفی از شناسه مشتری وجود دارد، بنابراین مطمئن شوید که نوع صحیح برنامه خود را دریافت کنید:

در هر یک از کدهای زیر (به جز حساب سرویس یک)، باید رمز مشتری را دانلود کرده و آن را به عنوان client_secrets.json در پروژه خود ذخیره کنید.

اعتبارنامه

اعتبار کاربر

UserCredential یک کلاس کمکی امن برای استفاده از یک نشانه دسترسی برای دسترسی به منابع محافظت شده است. یک نشانه دسترسی معمولاً پس از 1 ساعت منقضی می شود، پس از آن اگر سعی کنید از آن استفاده کنید با خطا مواجه می شوید.

UserCredential و AuthorizationCodeFlow از "رفرش" خودکار توکن مراقبت می کنند، که به سادگی به معنای دریافت رمز دسترسی جدید است. این کار با استفاده از یک نشانه رفرش طولانی مدت انجام می شود که در صورت استفاده از پارامتر access_type=offline در طول جریان کد مجوز، آن را به همراه نشانه دسترسی دریافت می کنید.

در اکثر برنامه‌ها، توصیه می‌شود که رمز دسترسی اعتبارنامه و نشانه تازه‌سازی در فضای ذخیره‌سازی دائمی ذخیره شود. در غیر این صورت، باید هر ساعت یک صفحه مجوز در مرورگر به کاربر نهایی ارائه دهید، زیرا رمز دسترسی یک ساعت پس از دریافت آن منقضی می‌شود.

برای اطمینان از تداوم توکن‌های دسترسی و به‌روزرسانی، می‌توانید پیاده‌سازی IDataStore خود را ارائه دهید، یا می‌توانید از یکی از پیاده‌سازی‌های زیر که توسط کتابخانه ارائه شده است استفاده کنید:

  • FileDataStore برای دات نت تضمین می کند که اعتبارنامه در یک فایل پایدار خواهد بود.

ServiceAccountCredential

ServiceAccountCredential مشابه UserCredential است، اما هدف متفاوتی دارد. Google OAuth 2.0 از تعاملات سرور به سرور مانند تعاملات بین یک برنامه وب و Google Cloud Storage پشتیبانی می کند. برنامه درخواست کننده باید هویت خود را ثابت کند تا به یک API دسترسی پیدا کند و کاربر نهایی لازم نیست درگیر باشد. ServiceAccountCredential یک کلید خصوصی را ذخیره می کند که برای امضای درخواست برای دریافت رمز دسترسی جدید استفاده می شود.

هر دو UserCredential و ServiceAccountCredential IConfigurableHttpClientInitializer پیاده سازی می کنند تا بتوانید هر یک از این موارد را به صورت زیر ثبت کنید:

  • یک کنترل کننده پاسخ ناموفق، بنابراین اگر کد وضعیت HTTP 401 را دریافت کند، رمز را تازه می کند.
  • یک رهگیر، برای رهگیری هدر Authorization در هر درخواست.

برنامه های نصب شده

کد نمونه با استفاده از Books API :

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

using Google.Apis.Auth.OAuth2;
using Google.Apis.Books.v1;
using Google.Apis.Books.v1.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;

namespace Books.ListMyLibrary
{
    /// <summary>
    /// Sample which demonstrates how to use the Books API.
    /// https://developers.google.com/books/docs/v1/getting_started
    /// <summary>
    internal class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Console.WriteLine("Books API Sample: List MyLibrary");
            Console.WriteLine("================================");
            try
            {
                new Program().Run().Wait();
            }
            catch (AggregateException ex)
            {
                foreach (var e in ex.InnerExceptions)
                {
                    Console.WriteLine("ERROR: " + e.Message);
                }
            }
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }

        private async Task Run()
        {
            UserCredential credential;
            using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
            {
                credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    new[] { BooksService.Scope.Books },
                    "user", CancellationToken.None, new FileDataStore("Books.ListMyLibrary"));
            }

            // Create the service.
            var service = new BooksService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Books API Sample",
                });

            var bookshelves = await service.Mylibrary.Bookshelves.List().ExecuteAsync();
            ...
        }
    }
}
  
  • در این کد نمونه یک نمونه UserCredential جدید با فراخوانی متد GoogleWebAuthorizationBroker.AuthorizeAsync ایجاد می شود. این روش استاتیک موارد زیر را دریافت می کند:

    • راز مشتری (یا جریانی به راز مشتری).
    • محدوده های مورد نیاز
    • شناسه کاربری
    • نشانه لغو برای لغو یک عملیات.
    • یک فروشگاه داده اختیاری اگر ذخیره داده مشخص نشده باشد، پیش فرض یک FileDataStore با پوشه پیش فرض Google.Apis.Auth است. پوشه در Environment.SpecialFolder.ApplicationData ایجاد می شود.
  • UserCredential که با این روش برگردانده می شود به عنوان HttpClientInitializer در BooksService (با استفاده از مقداردهی اولیه) تنظیم می شود. همانطور که در بالا توضیح داده شد، UserCredential یک اولیه ساز مشتری HTTP را پیاده سازی می کند.

  • توجه داشته باشید که در کد نمونه بالا، اطلاعات مخفی کلاینت از یک فایل بارگذاری می شود، اما می توانید کارهای زیر را نیز انجام دهید:

    credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
        new ClientSecrets
        {
            ClientId = "PUT_CLIENT_ID_HERE",
            ClientSecret = "PUT_CLIENT_SECRETS_HERE"
        },
        new[] { BooksService.Scope.Books },
        "user",
        CancellationToken.None,
        new FileDataStore("Books.ListMyLibrary"));
          

به نمونه کتاب های ما نگاهی بیندازید.

برنامه های کاربردی وب (ASP.NET Core 3)

API های Google از OAuth 2.0 برای برنامه های وب سرور پشتیبانی می کنند.

Google.Apis.Auth.AspNetCore3 کتابخانه توصیه شده برای استفاده برای اکثر سناریوهای مبتنی بر Google OAuth 2.0 در برنامه های ASP.NET Core 3 است. یک کنترل کننده تأیید اعتبار OpenIdConnect مخصوص گوگل را پیاده سازی می کند. از احراز هویت افزایشی پشتیبانی می‌کند و یک IGoogleAuthProvider تزریقی را برای ارائه اعتبارنامه‌های Google که می‌تواند با APIهای Google استفاده شود، تعریف می‌کند.

این بخش نحوه پیکربندی و استفاده از Google.Apis.Auth.AspNetCore3 را شرح می دهد. کد نشان داده شده در اینجا بر اساس Google.Apis.Auth.AspNetCore3.IntegrationTests است که یک برنامه کاملاً کارآمد و استاندارد ASP.NET Core 3 است.

اگر می‌خواهید این مستندات را به عنوان یک آموزش دنبال کنید، به برنامه ASP.NET Core 3 خود و تکمیل این مراحل به عنوان پیش نیاز نیاز دارید.

پیش نیازها

  • بسته Google.Apis.Auth.AspNetCore3 را نصب کنید.
  • ما از Google Drive API استفاده می کنیم، بنابراین شما باید بسته Google.Apis.Drive.v3 را نیز نصب کنید.
  • اگر قبلاً ندارید، یک پروژه Google Cloud ایجاد کنید. برای انجام این کار این دستورالعمل ها را دنبال کنید. این پروژه ای خواهد بود که برنامه شما با آن شناسایی می شود.
  • حتما Google Drive API را فعال کنید. برای فعال کردن API ها، این دستورالعمل ها را دنبال کنید.
  • اعتبارنامه مجوزی ایجاد کنید که برنامه شما را در Google شناسایی کند. برای ایجاد اعتبار مجوز و دانلود فایل client_secrets.json ، این دستورالعمل ها را دنبال کنید. دو نکته برجسته:
    • توجه داشته باشید که نوع اعتبارنامه باید برنامه وب باشد.
    • برای اجرای این برنامه، تنها URI تغییر مسیری که باید اضافه کنید https://localhost:5001/signin-oidc است.

برنامه خود را برای استفاده از Google.Apis.Auth.AspNetCore3 پیکربندی کنید

Google.Apis.Auth.AspNetCore3 در کلاس Startup یا جایگزین مشابهی که ممکن است استفاده کنید پیکربندی شده است. قطعه‌های زیر از Startup.cs در پروژه Google.Apis.Auth.AspNetCore3.IntegrationTests استخراج شده‌اند.

  • موارد زیر را با استفاده از دستورالعمل به فایل Startup.cs خود اضافه کنید.
    using Google.Apis.Auth.AspNetCore3;
  • در روش Startup.ConfigureServices کد زیر را اضافه کنید، Client ID و Client Secret را با مقادیر موجود در فایل client_secrets.json تغییر دهید. شما می توانید این مقادیر را مستقیماً از فایل JSON بارگیری کنید یا می توانید آنها را به روش های امن دیگری ذخیره کنید. نگاهی به روش ClientInfo.Load در پروژه Google.Apis.Auth.AspNetCore3.IntegrationTests بیندازید تا مثالی در مورد نحوه بارگیری مستقیم این مقادیر از فایل JSON داشته باشید.
    public void ConfigureServices(IServiceCollection services)
    {
        ...
    
        // This configures Google.Apis.Auth.AspNetCore3 for use in this app.
        services
            .AddAuthentication(o =>
            {
                // This forces challenge results to be handled by Google OpenID Handler, so there's no
                // need to add an AccountController that emits challenges for Login.
                o.DefaultChallengeScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
                // This forces forbid results to be handled by Google OpenID Handler, which checks if
                // extra scopes are required and does automatic incremental auth.
                o.DefaultForbidScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
                // Default scheme that will handle everything else.
                // Once a user is authenticated, the OAuth2 token info is stored in cookies.
                o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie()
            .AddGoogleOpenIdConnect(options =>
            {
                options.ClientId = {YOUR_CLIENT_ID};
                options.ClientSecret = {YOUR_CLIENT_SECRET};
            });
    }
          
  • در روش Startup.Configure ، مطمئن شوید که اجزای میان‌افزار احراز هویت و مجوز ASP.NET Core 3 و همچنین تغییر مسیرهای HTTPS را به خط لوله اضافه کنید:
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ...
        app.UseHttpsRedirection();
        ...
    
        app.UseAuthentication();
        app.UseAuthorization();
    
        ...
    }
          

از اعتبار کاربر برای دسترسی به APIهای Google از طرف آنها استفاده کنید

اکنون آماده هستید تا روش‌های اقدامی را به کنترل‌کننده‌های خود اضافه کنید که به اعتبار کاربری برای دسترسی به Google API از طرف آن‌ها نیاز دارد. قطعه زیر نحوه فهرست کردن فایل‌ها در حساب Google Drive کاربر تأیید شده را نشان می‌دهد. بیشتر به دو چیز توجه کنید:

  • کاربر نه تنها باید احراز هویت شود، بلکه باید دامنه https://www.googleapis.com/auth/drive.readonly را نیز به برنامه شما اعطا کند، که شما از طریق ویژگی GoogleScopedAuthorize آن را مشخص می کنید.
  • ما از مکانیسم تزریق وابستگی استاندارد ASP.NET Core 3 برای دریافت یک IGoogleAuthProvider استفاده می کنیم که برای به دست آوردن اعتبار کاربر از آن استفاده می کنیم.

کد:

  • ابتدا موارد زیر را با استفاده از دستورالعمل ها به کنترلر خود اضافه کنید.
    using Google.Apis.Auth.AspNetCore3;
    using Google.Apis.Auth.OAuth2;
    using Google.Apis.Drive.v3;
    using Google.Apis.Services;
          
  • عمل کنترلر را به صورت زیر اضافه کنید (و آن را با یک نمای ساده که یک مدل IList<string> دریافت می کند همراه کنید):
    /// <summary>
    /// Lists the authenticated user's Google Drive files.
    /// Specifying the <see cref="GoogleScopedAuthorizeAttribute"> will guarantee that the code
    /// executes only if the user is authenticated and has granted the scope specified in the attribute
    /// to this application.
    /// </summary>
    /// <param name="auth">The Google authorization provider.
    /// This can also be injected on the controller constructor.</param>
    [GoogleScopedAuthorize(DriveService.ScopeConstants.DriveReadonly)]
    public async Task<IActionResult> DriveFileList([FromServices] IGoogleAuthProvider auth)
    {
        GoogleCredential cred = await auth.GetCredentialAsync();
        var service = new DriveService(new BaseClientService.Initializer
        {
            HttpClientInitializer = cred
        });
        var files = await service.Files.List().ExecuteAsync();
        var fileNames = files.Files.Select(x => x.Name).ToList();
        return View(fileNames);
    }
          

و اینها اصول اولیه هستند. می‌توانید از پروژه Google.Apis.Auth.AspNetCore3.IntegrationTests به HomeController.cs نگاهی بیندازید تا دریابید که چگونه می‌توانید به آن دست پیدا کنید:

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

حساب خدمات

APIهای Google از حساب‌های سرویس پشتیبانی می‌کنند. برخلاف سناریویی که در آن یک برنامه مشتری درخواست دسترسی به داده‌های کاربر نهایی را می‌دهد، حساب‌های سرویس دسترسی به داده‌های خود برنامه مشتری را فراهم می‌کنند.

برنامه مشتری شما با استفاده از کلید خصوصی دانلود شده از Google API Console، درخواست یک نشانه دسترسی را امضا می کند. پس از ایجاد شناسه مشتری جدید، باید نوع برنامه «حساب سرویس» را انتخاب کنید و سپس می‌توانید کلید خصوصی را دانلود کنید. با استفاده از Google Plus API به نمونه حساب سرویس ما نگاهی بیندازید.

using System;
using System.Security.Cryptography.X509Certificates;

using Google.Apis.Auth.OAuth2;
using Google.Apis.Plus.v1;
using Google.Apis.Plus.v1.Data;
using Google.Apis.Services;

namespace Google.Apis.Samples.PlusServiceAccount
{
    /// <summary>
    /// This sample demonstrates the simplest use case for a Service Account service.
    /// The certificate needs to be downloaded from the Google API Console
    /// <see cref="https://console.cloud.google.com/">
    ///   "Create another client ID..." -> "Service Account" -> Download the certificate,
    ///   rename it as "key.p12" and add it to the project. Don't forget to change the Build action
    ///   to "Content" and the Copy to Output Directory to "Copy if newer".
    /// </summary>
    public class Program
    {
        // A known public activity.
        private static String ACTIVITY_ID = "z12gtjhq3qn2xxl2o224exwiqruvtda0i";

        public static void Main(string[] args)
        {
            Console.WriteLine("Plus API - Service Account");
            Console.WriteLine("==========================");

            String serviceAccountEmail = "SERVICE_ACCOUNT_EMAIL_HERE";

            var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable);

            ServiceAccountCredential credential = new ServiceAccountCredential(
               new ServiceAccountCredential.Initializer(serviceAccountEmail)
               {
                   Scopes = new[] { PlusService.Scope.PlusMe }
               }.FromCertificate(certificate));

            // Create the service.
            var service = new PlusService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "Plus API Sample",
            });

            Activity activity = service.Activities.Get(ACTIVITY_ID).Execute();
            Console.WriteLine("  Activity: " + activity.Object.Content);
            Console.WriteLine("  Video: " + activity.Object.Attachments[0].Url);

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
    }
}

کد نمونه بالا یک ServiceAccountCredential ایجاد می کند. دامنه های مورد نیاز تنظیم شده است و فراخوانی به FromCertificate وجود دارد که کلید خصوصی را از X509Certificate2 بارگیری می کند. مانند سایر کدهای نمونه، اعتبار به عنوان HttpClientInitializer تنظیم می شود.