Dokumen ini menjelaskan OAuth 2.0, waktu penggunaannya, cara memperoleh client ID, dan cara menggunakannya dengan Library Klien Google API untuk .NET.
Protokol OAuth 2.0
OAuth 2.0 adalah protokol otorisasi yang digunakan oleh Google API. Anda harus memahami protokol dengan membaca link berikut:
Memperoleh rahasia dan ID klien
Anda bisa mendapatkan client ID dan rahasia di Konsol API Google. Ada berbagai jenis client ID, jadi pastikan untuk mendapatkan jenis yang benar untuk aplikasi Anda:
- Client ID aplikasi web
- Client ID aplikasi yang diinstal
- ID klien akun layanan
Di setiap cuplikan kode di bawah (kecuali akun Layanan satu), Anda harus mendownload rahasia klien dan menyimpannya sebagai client_secrets.json
dalam project.
Kredensial
Kredensial pengguna
UserCredential
adalah class helper yang aman dari thread untuk menggunakan token akses untuk mengakses resource yang dilindungi.
Masa berlaku token akses biasanya berakhir setelah 1 jam, setelah itu Anda akan mendapatkan error jika Anda mencoba menggunakannya.
UserCredential
dan
AuthorizationCodeFlow
menangani "menyegarkan" secara otomatis; token, yang berarti memperoleh
token akses baru.
Hal ini dilakukan menggunakan token refresh yang berumur panjang, yang Anda terima bersama dengan token akses jika Anda menggunakan parameter access_type=offline
selama alur kode otorisasi.
Di sebagian besar aplikasi, sebaiknya simpan token akses dan token refresh kredensial di penyimpanan persisten. Jika tidak, Anda harus menampilkan halaman otorisasi di browser kepada pengguna akhir setiap jam, karena token akses akan berakhir satu jam setelah Anda menerimanya.
Untuk memastikan token akses dan refresh tetap ada, Anda dapat memberikan implementasi IDataStore
sendiri, atau menggunakan salah satu implementasi berikut yang disediakan oleh library:
-
FileDataStore
untuk .NET memastikan bahwa kredensial akan tetap berada dalam file.
KredensialAkunLayanan
ServiceAccountCredential
serupa dengan UserCredential
, tetapi memiliki tujuan yang berbeda.
Google OAuth 2.0 mendukung interaksi server ke server seperti interaksi antara aplikasi web dan Google Cloud Storage.
Aplikasi yang meminta harus membuktikan identitasnya sendiri untuk mendapatkan akses ke API, dan pengguna akhir tidak harus terlibat.
ServiceAccountCredential
menyimpan kunci pribadi, yang digunakan untuk menandatangani permintaan guna mendapatkan token akses baru.
UserCredential
dan ServiceAccountCredential
menerapkan
IConfigurableHttpClientInitializer
sehingga Anda dapat mendaftarkan masing-masing metode sebagai:
- Pengendali respons yang gagal, sehingga akan memuat ulang token jika menerima kode status
401
HTTP. - Intersektor, untuk mencegat header
Authorization
pada setiap permintaan.
Aplikasi terpasang
Kode contoh menggunakan 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(); ... } } }
-
Dalam kode contoh ini, instance
UserCredential
baru dibuat dengan memanggil metodeGoogleWebAuthorizationBroker.AuthorizeAsync
. Metode statis ini mendapatkan hal berikut:- Rahasia klien (atau streaming ke rahasia klien).
- Cakupan yang diperlukan.
- ID pengguna.
- Token pembatalan untuk membatalkan operasi.
- Penyimpanan data opsional. Jika penyimpanan data tidak ditentukan, defaultnya adalah
FileDataStore
dengan folderGoogle.Apis.Auth
default. Folder ini dibuat diEnvironment.SpecialFolder.ApplicationData
.
-
UserCredential
yang ditampilkan oleh metode ini ditetapkan sebagaiHttpClientInitializer
diBooksService
(menggunakan penginisialisasi). Seperti yang dijelaskan di atas,UserCredential
mengimplementasikan penginisialisasi klien HTTP. -
Perhatikan bahwa dalam kode contoh di atas, informasi rahasia klien dimuat dari file, tetapi Anda juga dapat melakukan hal berikut:
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"));
Lihat contoh Buku kami.
Aplikasi web (ASP.NET Core 3)
Google API mendukung OAuth 2.0 untuk Aplikasi Server Web.
Google.Apis.Auth.AspNetCore3 adalah library yang direkomendasikan untuk digunakan bagi sebagian besar skenario OAuth 2.0 berbasis Google di aplikasi ASP.NET Core 3. Metode ini menerapkan pengendali autentikasi OpenIdConnect
khusus Google. API ini mendukung autentikasi inkremental, dan menentukan IGoogleAuthProvider
yang dapat dimasukkan untuk menyediakan kredensial Google yang dapat digunakan dengan Google API.
Bagian ini menjelaskan cara mengonfigurasi dan menggunakan Google.Apis.Auth.AspNetCore3. Kode yang ditampilkan di sini didasarkan pada Google.Apis.Auth.AspNetCore3.IntegrationsTests yang merupakan aplikasi ASP.NET Core 3 standar yang berfungsi sepenuhnya.
Jika ingin mengikuti dokumentasi ini sebagai tutorial, Anda memerlukan aplikasi ASP.NET Core 3 sendiri dan menyelesaikan langkah-langkah ini sebagai prasyarat.
Prasyarat
- Instal paket Google.Apis.Auth.AspNetCore3.
- Kami menggunakan Google Drive API sehingga Anda juga perlu menginstal paket Google.Apis.Drive.v3.
- Buat project Google Cloud jika Anda belum memilikinya. Ikuti petunjuk ini untuk melakukannya. Project ini akan menjadi project yang diidentifikasi dengan aplikasi Anda.
- Pastikan untuk mengaktifkan Google Drive API. Untuk mengaktifkan API, ikuti petunjuk ini.
-
Buat kredensial otorisasi yang akan mengidentifikasi aplikasi Anda ke Google. Ikuti
petunjuk ini untuk membuat kredensial otorisasi dan mendownload file
client_secrets.json
. Dua sorotan:- Perhatikan bahwa jenis kredensial harus Aplikasi web.
- Untuk menjalankan aplikasi ini, satu-satunya URI pengalihan yang perlu Anda tambahkan adalah
https://localhost:5001/signin-oidc
.
Konfigurasikan aplikasi Anda untuk menggunakan Google.Apis.Auth.AspNetCore3
Google.Apis.Auth.AspNetCore3 dikonfigurasi di class Startup
atau alternatif serupa yang mungkin Anda gunakan. Cuplikan berikut diekstrak dari
Startup.cs
dalam project Google.Apis.Auth.AspNetCore3.IntegrationsTests.
-
Tambahkan perintah berikut menggunakan perintah ke file
Startup.cs
Anda.using Google.Apis.Auth.AspNetCore3;
-
Di metode
Startup.ConfigureServices
, tambahkan kode berikut, ubah Client-ID dan placeholder Rahasia Klien dengan nilai yang terdapat dalam fileclient_secrets.json
. Anda dapat memuat nilai ini langsung dari file JSON atau menyimpannya dengan cara lain yang aman. Lihat metodeClientInfo.Load
di project Google.Apis.Auth.AspNetCore3.IntegrationsTests untuk mengetahui contoh cara memuat nilai ini langsung dari file 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}; }); }
-
Dalam metode
Startup.Configure
, pastikan untuk menambahkan komponen autentikasi dan otorisasi ASP.NET Core 3 ke pipeline, serta pengalihan HTTPS:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... app.UseHttpsRedirection(); ... app.UseAuthentication(); app.UseAuthorization(); ... }
Menggunakan kredensial pengguna untuk mengakses Google API atas nama mereka
Anda kini siap menambahkan metode tindakan ke pengontrol yang memerlukan kredensial pengguna untuk mengakses Google API atas nama mereka. Cuplikan berikut menunjukkan cara menampilkan daftar file di akun Google Drive pengguna yang diautentikasi. Perhatikan dua hal:
-
Pengguna tidak hanya perlu diautentikasi, tetapi juga harus memberikan cakupan
https://www.googleapis.com/auth/drive.readonly
ke aplikasi Anda, yang Anda tentukan melalui atributGoogleScopedAuthorize
. -
Kami menggunakan mekanisme injeksi dependensi standar ASP.NET Core 3 untuk menerima
IGoogleAuthProvider
yang kami gunakan untuk mendapatkan kredensial pengguna.
Kode:
-
Pertama-tama, tambahkan hal berikut menggunakan perintah ke pengontrol.
using Google.Apis.Auth.AspNetCore3; using Google.Apis.Auth.OAuth2; using Google.Apis.Drive.v3; using Google.Apis.Services;
-
Tambahkan tindakan pengontrol, seperti berikut (dan menyertainya dengan tampilan sederhana
yang menerima model
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); }
Dan ini adalah dasar-dasarnya. Anda dapat melihat
HomeController.cs
dari project Google.Apis.Auth.AspNetCore3.IntegrationsTests
untuk mengetahui cara mencapai:
- Autentikasi pengguna saja, tanpa cakupan spesifik
- Fungsi logout
- Otorisasi inkremental melalui kode. Perhatikan bahwa cuplikan di atas menunjukkan otorisasi inkremental melalui atribut.
- Memeriksa cakupan yang saat ini diberikan
- Memeriksa akses dan memperbarui token
- Muat ulang token akses secara paksa. Perhatikan bahwa Anda tidak perlu melakukannya sendiri karena Google.Apis.Auth.AspNetCore3 akan mendeteksi apakah token akses sudah tidak berlaku atau hampir habis masa berlakunya dan akan memperbaruinya secara otomatis.
Aplikasi web (ASP.NET MVC)
Google API mendukung
OAuth 2.0 untuk Aplikasi Server Web.
Agar berhasil menjalankan kode berikut, Anda harus terlebih dahulu menambahkan URI pengalihan ke
project Anda di Konsol API Google.
Karena Anda akan menggunakan FlowMetadata
dan setelan defaultnya,
setel URI pengalihan ke
your_site/AuthCallback/IndexAsync
.
Untuk menemukan URI pengalihan untuk kredensial OAuth 2.0 Anda, lakukan hal berikut:
- Buka halaman Credentials di Konsol API.
- Buat kredensial OAuth 2.0 dengan mengklik Buat kredensial > client ID OAuth jika Anda belum melakukannya.
- Setelah membuat kredensial, lihat atau edit URL alihan dengan mengklik client ID (untuk aplikasi web) di bagian Client ID OAuth 2.0.
Setelah membuat project aplikasi web baru di IDE Anda, tambahkan paket NuGet Google.Apis
yang tepat untuk Drive, YouTube, atau layanan lain yang ingin Anda gunakan. Kemudian, tambahkan paket Google.Apis.Auth.MVC.
Kode berikut menunjukkan aplikasi ASP.NET MVC yang membuat kueri layanan Google API.
-
Tambahkan implementasi
FlowMetadata
Anda sendiri.using System; using System.Web.Mvc; using Google.Apis.Auth.OAuth2; using Google.Apis.Auth.OAuth2.Flows; using Google.Apis.Auth.OAuth2.Mvc; using Google.Apis.Drive.v2; using Google.Apis.Util.Store; namespace Google.Apis.Sample.MVC4 { public class AppFlowMetadata : FlowMetadata { private static readonly IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = new ClientSecrets { ClientId = "PUT_CLIENT_ID_HERE", ClientSecret = "PUT_CLIENT_SECRET_HERE" }, Scopes = new[] { DriveService.Scope.Drive }, DataStore = new FileDataStore("Drive.Api.Auth.Store") }); public override string GetUserId(Controller controller) { // In this sample we use the session to store the user identifiers. // That's not the best practice, because you should have a logic to identify // a user. You might want to use "OpenID Connect". // You can read more about the protocol in the following link: // https://developers.google.com/accounts/docs/OAuth2Login. var user = controller.Session["user"]; if (user == null) { user = Guid.NewGuid(); controller.Session["user"] = user; } return user.ToString(); } public override IAuthorizationCodeFlow Flow { get { return flow; } } } }
FlowMetadata
adalah class abstrak yang berisi logika Anda sendiri untuk mengambil ID pengguna danIAuthorizationCodeFlow
yang Anda gunakan.Pada kode contoh di atas,
GoogleAuthorizationCodeFlow
baru dibuat dengan cakupan yang tepat, rahasia klien, dan penyimpanan data. Pertimbangkan untuk menambahkan implementasiIDataStore
sendiri, misalnya, Anda dapat menulis implementasi yang menggunakanEntityFramework
. -
Terapkan pengontrol Anda sendiri yang menggunakan layanan Google API.
Contoh berikut menggunakan
DriveService
:using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Web.Mvc; using Google.Apis.Auth.OAuth2.Mvc; using Google.Apis.Drive.v2; using Google.Apis.Services; using Google.Apis.Sample.MVC4; namespace Google.Apis.Sample.MVC4.Controllers { public class HomeController : Controller { public async Task<ActionResult> IndexAsync(CancellationToken cancellationToken) { var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()). AuthorizeAsync(cancellationToken); if (result.Credential != null) { var service = new DriveService(new BaseClientService.Initializer { HttpClientInitializer = result.Credential, ApplicationName = "ASP.NET MVC Sample" }); // YOUR CODE SHOULD BE HERE.. // SAMPLE CODE: var list = await service.Files.List().ExecuteAsync(); ViewBag.Message = "FILE COUNT IS: " + list.Items.Count(); return View(); } else { return new RedirectResult(result.RedirectUri); } } } }
-
Terapkan pengontrol callback Anda sendiri. Implementasinya akan terlihat seperti ini:
using Google.Apis.Sample.MVC4; namespace Google.Apis.Sample.MVC4.Controllers { public class AuthCallbackController : Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController { protected override Google.Apis.Auth.OAuth2.Mvc.FlowMetadata FlowData { get { return new AppFlowMetadata(); } } } }
Akun layanan
Google API juga mendukung Akun layanan. Tidak seperti skenario yang menyebabkan aplikasi klien meminta akses ke data pengguna akhir, akun layanan memberikan akses ke data aplikasi klien.
Aplikasi klien Anda menandatangani permintaan untuk token akses menggunakan kunci pribadi yang didownload dari Konsol API Google. Setelah membuat client ID baru, Anda harus memilih jenis aplikasi “Akun Layanan”, lalu Anda dapat mendownload kunci pribadi. Lihat contoh akun layanan kami menggunakan 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(); } } }
Kode contoh di atas membuat
ServiceAccountCredential
.
Cakupan yang diperlukan ditetapkan dan ada panggilan ke FromCertificate
, yang memuat kunci pribadi dari X509Certificate2
yang diberikan.
Seperti di semua kode contoh lainnya, kredensial ditetapkan sebagai HttpClientInitializer
.