OAuth 2.0 untuk Aplikasi Web Sisi Klien

Dokumen ini menjelaskan cara menerapkan otorisasi OAuth 2.0 untuk mengakses Google API dari aplikasi web JavaScript. OAuth 2.0 memungkinkan pengguna membagikan data tertentu dengan aplikasi, sekaligus menjaga kerahasiaan nama pengguna, sandi, dan informasi mereka lainnya. Misalnya, aplikasi dapat menggunakan OAuth 2.0 untuk mendapatkan izin dari pengguna untuk menyimpan file di Google Drive mereka.

Alur OAuth 2.0 ini disebut alur pemberian implisit. Fitur ini dirancang untuk aplikasi yang mengakses API hanya saat pengguna berada di aplikasi. Aplikasi ini tidak dapat menyimpan informasi rahasia.

Dalam alur ini, aplikasi Anda membuka URL Google yang menggunakan parameter kueri untuk mengidentifikasi aplikasi Anda dan jenis akses API yang diperlukan aplikasi. Anda dapat membuka URL di jendela browser saat ini atau pop-up. Pengguna dapat mengautentikasi dengan Google dan memberikan izin yang diminta. Kemudian, Google mengalihkan pengguna kembali ke aplikasi Anda. Pengalihan ini mencakup token akses, yang diverifikasi oleh aplikasi Anda, lalu digunakan untuk membuat permintaan API.

Library Klien Google API dan Layanan Identitas Google

Jika Anda menggunakan library klien Google API untuk JavaScript untuk melakukan panggilan yang sah ke Google, Anda harus menggunakan library JavaScript Google Identity Services untuk menangani alur OAuth 2.0. Lihat model token Google Identity Services, yang didasarkan pada alur pemberian implisit OAuth 2.0.

Prasyarat

Aktifkan API untuk project Anda

Setiap aplikasi yang memanggil Google API harus mengaktifkan API tersebut di API Console.

Untuk mengaktifkan API untuk project Anda:

  1. Open the API Library di Google API Console.
  2. If prompted, select a project, or create a new one.
  3. API Library mencantumkan semua API yang tersedia, yang dikelompokkan berdasarkan kelompok produk dan popularitas. Jika API yang ingin Anda aktifkan tidak terlihat dalam daftar, gunakan penelusuran untuk mencarinya, atau klik Lihat Semua dalam kelompok produk yang terkait.
  4. Pilih API yang ingin Anda aktifkan, lalu klik tombol Aktifkan.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Membuat kredensial otorisasi

Setiap aplikasi yang menggunakan OAuth 2.0 untuk mengakses Google API harus memiliki kredensial otorisasi yang mengidentifikasi aplikasi ke server OAuth 2.0 Google. Langkah-langkah berikut menjelaskan cara membuat kredensial untuk project Anda. Aplikasi Anda kemudian dapat menggunakan kredensial untuk mengakses API yang telah Anda aktifkan untuk project tersebut.

  1. Go to the Credentials page.
  2. Klik Buat Klien.
  3. Pilih jenis aplikasi Web application.
  4. Isi formulir. Aplikasi yang menggunakan JavaScript untuk membuat permintaan Google API yang sah harus menentukan asal JavaScript yang sah. Asal mengidentifikasi domain dari tempat aplikasi Anda dapat mengirim permintaan ke server OAuth 2.0. Asal ini harus mematuhi aturan validasi Google.

Mengidentifikasi cakupan akses

Cakupan memungkinkan aplikasi Anda hanya meminta akses ke resource yang diperlukan sekaligus memungkinkan pengguna mengontrol jumlah akses yang mereka berikan ke aplikasi Anda. Oleh karena itu, mungkin ada hubungan terbalik antara jumlah cakupan yang diminta dan kemungkinan mendapatkan izin pengguna.

Sebelum mulai menerapkan otorisasi OAuth 2.0, sebaiknya Anda mengidentifikasi cakupan yang izin aksesnya akan diperlukan oleh aplikasi Anda.

Dokumen Cakupan API OAuth 2.0 berisi daftar lengkap cakupan yang dapat Anda gunakan untuk mengakses Google API.

Mendapatkan token akses OAuth 2.0

Langkah-langkah berikut menunjukkan cara aplikasi Anda berinteraksi dengan server OAuth 2.0 Google untuk mendapatkan izin pengguna dalam melakukan permintaan API atas nama pengguna. Aplikasi Anda harus memiliki izin tersebut sebelum dapat mengeksekusi permintaan Google API yang memerlukan otorisasi pengguna.

Langkah 1: Lakukan pengalihan ke server OAuth 2.0 Google

Untuk meminta izin mengakses data pengguna, alihkan pengguna ke server OAuth 2.0 Google.

Endpoint OAuth 2.0

Buat URL untuk meminta akses dari endpoint OAuth 2.0 Google di https://accounts.google.com/o/oauth2/v2/auth. Endpoint ini dapat diakses melalui HTTPS; koneksi HTTP biasa ditolak.

Server otorisasi Google mendukung parameter string kueri berikut untuk aplikasi server web:

Parameter
client_id Wajib

Client ID untuk aplikasi Anda. Anda dapat menemukan nilai ini di .

redirect_uri Wajib

Menentukan ke mana server API mengalihkan pengguna setelah pengguna menyelesaikan alur otorisasi. Nilai harus sama persis dengan salah satu URI pengalihan yang diberi otorisasi untuk klien OAuth 2.0, yang Anda konfigurasi di klien. Jika nilai ini tidak cocok dengan URI pengalihan yang sah untuk client_id yang diberikan, Anda akan mendapatkan error redirect_uri_mismatch.

Perhatikan bahwa skema http atau https, huruf besar/kecil, dan garis miring di akhir ('/') harus sama.

response_type Wajib

Aplikasi JavaScript perlu menetapkan nilai parameter ke token. Nilai ini menginstruksikan Server Otorisasi Google untuk menampilkan token akses sebagai pasangan name=value dalam ID fragmen URI (#) yang menjadi tujuan pengalihan pengguna setelah menyelesaikan proses otorisasi.

scope Wajib

Daftar cakupan yang dibatasi spasi yang mengidentifikasi resource yang dapat diakses aplikasi Anda atas nama pengguna. Nilai ini memberi tahu layar izin yang ditampilkan Google kepada pengguna.

Cakupan memungkinkan aplikasi Anda hanya meminta akses ke resource yang dibutuhkan sekaligus memungkinkan pengguna mengontrol jumlah akses yang mereka berikan ke aplikasi Anda. Dengan demikian, ada hubungan terbalik antara jumlah cakupan yang diminta dan kemungkinan mendapatkan izin pengguna.

Sebaiknya aplikasi Anda meminta akses ke cakupan otorisasi dalam konteks jika memungkinkan. Dengan meminta akses ke data pengguna sesuai konteks, melalui otorisasi tambahan, Anda membantu pengguna lebih mudah memahami alasan aplikasi Anda memerlukan akses yang dimintanya.

state Direkomendasikan

Menentukan nilai string apa pun yang digunakan aplikasi Anda untuk mempertahankan status antara permintaan otorisasi dan respons server otorisasi. Server menampilkan nilai persis yang Anda kirim sebagai pasangan name=value di ID fragmen URL (#) dari redirect_uri setelah pengguna menyetujui atau menolak permintaan akses aplikasi Anda.

Anda dapat menggunakan parameter ini untuk beberapa tujuan, seperti mengarahkan pengguna ke resource yang benar di aplikasi Anda, mengirim nonce, dan memitigasi pemalsuan permintaan lintas situs. Karena redirect_uri Anda dapat ditebak, menggunakan nilai state dapat meningkatkan kepastian Anda bahwa koneksi masuk adalah hasil dari permintaan autentikasi. Jika Anda membuat string acak atau mengenkode hash cookie atau nilai lain yang merekam status klien, Anda dapat memvalidasi respons untuk memastikan lebih lanjut bahwa permintaan dan respons berasal dari browser yang sama, sehingga memberikan perlindungan terhadap serangan seperti pemalsuan permintaan lintas situs. Lihat dokumentasi OpenID Connect untuk mengetahui contoh cara membuat dan mengonfirmasi token state.

include_granted_scopes Opsional

Memungkinkan aplikasi menggunakan otorisasi tambahan untuk meminta akses ke cakupan tambahan dalam konteks. Jika Anda menyetel nilai parameter ini ke true dan permintaan otorisasi diberikan, token akses baru juga akan mencakup cakupan apa pun yang sebelumnya diberikan akses oleh pengguna ke aplikasi. Lihat bagian otorisasi inkremental untuk mengetahui contohnya.

login_hint Opsional

Jika aplikasi Anda mengetahui pengguna mana yang mencoba melakukan autentikasi, aplikasi tersebut dapat menggunakan parameter ini untuk memberikan petunjuk ke Server Autentikasi Google. Server menggunakan petunjuk untuk menyederhanakan alur login dengan mengisi otomatis kolom email di formulir login atau dengan memilih sesi multi-login yang sesuai.

Tetapkan nilai parameter ke alamat email atau ID sub, yang setara dengan ID Google pengguna.

prompt Opsional

Daftar perintah yang dipisahkan dengan spasi dan peka huruf besar/kecil untuk ditampilkan kepada pengguna. Jika Anda tidak menentukan parameter ini, pengguna hanya akan dimintai izin saat project Anda meminta akses untuk pertama kalinya. Lihat Meminta izin ulang untuk mengetahui informasi selengkapnya.

Nilai yang dimungkinkan adalah:

none Jangan menampilkan layar autentikasi atau izin apa pun. Tidak boleh ditentukan dengan nilai lain.
consent Minta izin pengguna.
select_account Minta pengguna untuk memilih akun.

Contoh pengalihan ke server otorisasi Google

Contoh URL ditampilkan di bawah, dengan jeda baris dan spasi agar mudah dibaca.

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&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Setelah membuat URL permintaan, alihkan pengguna ke URL tersebut.

Contoh kode JavaScript

Cuplikan JavaScript berikut menunjukkan cara memulai alur otorisasi di JavaScript tanpa menggunakan Library Klien Google API untuk JavaScript. Karena endpoint OAuth 2.0 ini tidak mendukung Cross-Origin Resource Sharing (CORS), cuplikan membuat formulir yang membuka permintaan ke endpoint tersebut.

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

Langkah 2: Google meminta izin pengguna

Pada langkah ini, pengguna memutuskan apakah akan memberikan akses yang diminta ke aplikasi Anda. Pada tahap ini, Google menampilkan jendela izin yang menunjukkan nama aplikasi Anda dan layanan Google API yang meminta izin untuk mengakses dengan kredensial otorisasi pengguna dan ringkasan cakupan akses yang akan diberikan. Pengguna kemudian dapat menyetujui untuk memberikan akses ke satu atau beberapa cakupan yang diminta oleh aplikasi Anda atau menolak permintaan.

Aplikasi Anda tidak perlu melakukan apa pun pada tahap ini karena menunggu respons dari server OAuth 2.0 Google yang menunjukkan apakah ada akses yang diberikan. Respons tersebut dijelaskan pada langkah berikutnya.

Error

Permintaan ke endpoint otorisasi OAuth 2.0 Google dapat menampilkan pesan error yang terlihat oleh pengguna, bukan alur autentikasi dan otorisasi yang diharapkan. Kode error umum dan saran penyelesaiannya tercantum di bawah.

admin_policy_enforced

Akun Google tidak dapat mengizinkan satu atau beberapa cakupan yang diminta karena kebijakan administrator Google Workspace-nya. Lihat artikel bantuan Admin Google Workspace Mengontrol aplikasi pihak ketiga & internal yang mengakses data Google Workspace untuk mengetahui informasi selengkapnya tentang cara administrator dapat membatasi akses ke semua cakupan atau cakupan sensitif dan terbatas hingga akses diberikan secara eksplisit ke ID klien OAuth Anda.

disallowed_useragent

Endpoint otorisasi ditampilkan di dalam agen pengguna sematan yang tidak diizinkan oleh Kebijakan OAuth 2.0 Google.

Android

Developer Android mungkin melihat pesan error ini saat membuka permintaan otorisasi di android.webkit.WebView. Sebagai gantinya, developer harus menggunakan library Android seperti Login dengan Google untuk Android atau AppAuth untuk Android dari OpenID Foundation.

Developer web mungkin mengalami error ini saat aplikasi Android membuka link web umum di agen pengguna yang disematkan dan pengguna membuka endpoint otorisasi OAuth 2.0 Google dari situs Anda. Developer harus mengizinkan link umum dibuka di pengendali link default sistem operasi, yang mencakup pengendali Link Aplikasi Android atau aplikasi browser default. Library Tab Kustom Android juga merupakan opsi yang didukung.

iOS

Developer iOS dan macOS mungkin mengalami error ini saat membuka permintaan otorisasi di WKWebView. Sebagai gantinya, developer harus menggunakan library iOS seperti Login dengan Google untuk iOS atau AppAuth untuk iOS dari OpenID Foundation.

Developer web mungkin mengalami error ini saat aplikasi iOS atau macOS membuka link web umum di agen pengguna yang disematkan dan pengguna membuka endpoint otorisasi OAuth 2.0 Google dari situs Anda. Developer harus mengizinkan link umum dibuka di pengendali link default sistem operasi, yang mencakup pengendali Universal Link atau aplikasi browser default. Library SFSafariViewController juga merupakan opsi yang didukung.

org_internal

ID klien OAuth dalam permintaan adalah bagian dari project yang membatasi akses ke Akun Google di Organisasi Google Cloud tertentu. Untuk mengetahui informasi selengkapnya tentang opsi konfigurasi ini, lihat bagian Jenis pengguna di artikel bantuan Menyiapkan layar izin OAuth.

invalid_client

Asal tempat permintaan dibuat tidak diizinkan untuk klien ini. Lihat origin_mismatch.

deleted_client

Klien OAuth yang digunakan untuk membuat permintaan telah dihapus. Penghapusan dapat terjadi secara manual atau otomatis dalam kasus klien yang tidak digunakan . Klien yang dihapus dapat dipulihkan dalam waktu 30 hari setelah penghapusan. Pelajari lebih lanjut .

invalid_grant

Saat menggunakan otorisasi inkremental, token mungkin sudah tidak berlaku atau telah dibatalkan. Lakukan autentikasi ulang pengguna dan minta izin pengguna untuk mendapatkan token baru. Jika Anda terus melihat error ini, pastikan aplikasi Anda telah dikonfigurasi dengan benar dan Anda menggunakan token dan parameter yang benar dalam permintaan Anda. Jika tidak, akun pengguna mungkin telah dihapus atau dinonaktifkan.

origin_mismatch

Skema, domain, dan/atau port JavaScript yang memulai permintaan otorisasi mungkin tidak cocok dengan URI asal JavaScript resmi yang terdaftar untuk ID klien OAuth. Tinjau asal JavaScript resmi di .

redirect_uri_mismatch

redirect_uri yang diteruskan dalam permintaan otorisasi tidak cocok dengan URI pengalihan yang diberi otorisasi untuk ID klien OAuth. Tinjau URI pengalihan yang sah di .

Skema, domain, dan/atau port JavaScript yang memulai permintaan otorisasi mungkin tidak cocok dengan URI asal JavaScript resmi yang terdaftar untuk ID klien OAuth. Tinjau asal JavaScript resmi di .

Parameter redirect_uri dapat merujuk ke alur OAuth di luar band (OOB) yang sudah tidak digunakan lagi dan tidak didukung lagi. Lihat panduan migrasi untuk memperbarui integrasi Anda.

invalid_request

Terjadi kesalahan pada permintaan yang Anda buat. Hal ini dapat disebabkan oleh beberapa alasan:

  • Permintaan tidak diformat dengan benar
  • Permintaan tidak memiliki parameter yang diperlukan
  • Permintaan menggunakan metode otorisasi yang tidak didukung Google. Memverifikasi bahwa integrasi OAuth Anda menggunakan metode integrasi yang direkomendasikan

Langkah 3: Tangani respons server OAuth 2.0

Endpoint OAuth 2.0

Server OAuth 2.0 mengirimkan respons ke redirect_uri yang ditentukan dalam permintaan token akses Anda.

Jika pengguna menyetujui permintaan, respons akan berisi token akses. Jika pengguna tidak menyetujui permintaan tersebut, respons akan berisi pesan error. Token akses atau pesan error ditampilkan pada fragmen hash URI pengalihan, seperti yang ditunjukkan di bawah ini:

  • Respons token akses:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    Selain parameter access_token, string fragmen juga berisi parameter token_type, yang selalu ditetapkan ke Bearer, dan parameter expires_in, yang menentukan masa berlaku token, dalam detik. Jika parameter state ditentukan dalam permintaan token akses, nilainya juga disertakan dalam respons.

  • Respons error:
    https://oauth2.example.com/callback#error=access_denied

Contoh respons server OAuth 2.0

Anda dapat menguji alur ini dengan mengklik contoh URL berikut, yang meminta akses hanya baca untuk melihat metadata file di Google Drive Anda dan akses hanya baca untuk melihat acara Google Kalender Anda:

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&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Setelah menyelesaikan alur OAuth 2.0, Anda akan dialihkan ke http://localhost/oauth2callback. URL tersebut akan menghasilkan error 404 NOT FOUND kecuali jika komputer lokal Anda kebetulan menayangkan file di alamat tersebut. Langkah berikutnya memberikan detail selengkapnya tentang informasi yang ditampilkan di URI saat pengguna dialihkan kembali ke aplikasi Anda.

Langkah 4: Periksa cakupan yang diberikan pengguna

Saat meminta beberapa izin (cakupan), pengguna mungkin tidak memberikan akses aplikasi Anda ke semua izin tersebut. Aplikasi Anda harus memverifikasi cakupan mana yang benar-benar diberikan dan menangani situasi dengan baik saat beberapa izin ditolak, biasanya dengan menonaktifkan fitur yang mengandalkan cakupan yang ditolak tersebut.

Namun, ada pengecualian. Aplikasi Google Workspace Enterprise dengan delegasi otoritas di seluruh domain, atau aplikasi yang ditandai sebagai Tepercaya, melewati layar izin izin terperinci. Untuk aplikasi ini, pengguna tidak akan melihat layar izin izin terperinci. Sebagai gantinya, aplikasi Anda akan menerima semua cakupan yang diminta atau tidak sama sekali.

Untuk informasi yang lebih mendetail, lihat Cara menangani izin terperinci.

Endpoint OAuth 2.0

Untuk memeriksa apakah pengguna telah memberikan akses aplikasi Anda ke cakupan tertentu, periksa kolom scope dalam respons token akses. Cakupan akses yang diberikan oleh access_token dinyatakan sebagai daftar string peka huruf besar/kecil yang dipisahkan spasi.

Misalnya, respons token akses contoh berikut menunjukkan bahwa pengguna telah memberikan akses aplikasi Anda ke izin aktivitas Drive dan acara Kalender hanya baca:

  {
    "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"
  }

Memanggil Google API

Endpoint OAuth 2.0

Setelah aplikasi Anda mendapatkan token akses, Anda dapat menggunakan token tersebut untuk melakukan panggilan ke Google API atas nama akun pengguna tertentu jika cakupan akses yang diperlukan oleh API telah diberikan. Untuk melakukannya, sertakan token akses dalam permintaan ke API dengan menyertakan parameter kueri access_token atau nilai header HTTP Authorization Bearer. Jika memungkinkan, header HTTP lebih disarankan, karena string kueri cenderung terlihat dalam log server. Dalam sebagian besar kasus, Anda dapat menggunakan library klien untuk menyiapkan panggilan ke Google API (misalnya, saat memanggil Drive Files API).

Anda dapat mencoba semua Google API dan melihat cakupannya di OAuth 2.0 Playground.

Contoh HTTP GET

Panggilan ke drive.files endpoint (Drive Files API) menggunakan header HTTP Authorization: Bearer mungkin terlihat seperti berikut. Perhatikan bahwa Anda harus menentukan token akses Anda sendiri:

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

Berikut adalah panggilan ke API yang sama untuk pengguna yang diautentikasi menggunakan parameter string kueri access_token:

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

Contoh curl

Anda dapat menguji perintah ini dengan aplikasi command line curl. Berikut adalah contoh yang menggunakan opsi header HTTP (lebih disarankan):

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

Atau, opsi parameter string kueri:

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

Contoh kode JavaScript

Cuplikan kode di bawah menunjukkan cara menggunakan CORS (Cross-origin resource sharing) untuk mengirim permintaan ke Google API. Contoh ini tidak menggunakan Library Klien Google API untuk JavaScript. Namun, meskipun Anda tidak menggunakan library klien, panduan dukungan CORS dalam dokumentasi library tersebut kemungkinan akan membantu Anda untuk lebih memahami permintaan ini.

Dalam cuplikan kode ini, variabel access_token mewakili token yang telah Anda peroleh untuk membuat permintaan API atas nama pengguna yang berwenang. Contoh lengkap menunjukkan cara menyimpan token tersebut di penyimpanan lokal browser dan mengambilnya saat membuat permintaan API.

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

Contoh lengkap

Endpoint OAuth 2.0

Contoh kode ini menunjukkan cara menyelesaikan alur OAuth 2.0 di JavaScript tanpa menggunakan Library Klien Google API untuk JavaScript. Kode ini adalah untuk halaman HTML yang menampilkan tombol untuk mencoba permintaan API. Jika Anda mengklik tombol, kode akan memeriksa apakah halaman telah menyimpan token akses API di penyimpanan lokal browser Anda. Jika ya, permintaan API akan dieksekusi. Jika tidak, OAuth 2.0 akan dimulai.

Untuk alur OAuth 2.0, halaman mengikuti langkah-langkah berikut:

  1. Aplikasi ini mengarahkan pengguna ke server OAuth 2.0 Google, yang meminta akses ke cakupan https://www.googleapis.com/auth/drive.metadata.readonly dan https://www.googleapis.com/auth/calendar.readonly.
  2. Setelah memberikan (atau menolak) akses ke satu atau beberapa cakupan yang diminta, pengguna akan dialihkan ke halaman asli, yang mengurai token akses dari string ID fragmen.
  3. Halaman ini memeriksa cakupan mana yang telah diberikan akses oleh pengguna ke aplikasi.
  4. Jika pengguna telah memberikan akses ke cakupan yang diminta, halaman akan menggunakan token akses untuk membuat contoh permintaan API.

    Permintaan API memanggil metode about.get Drive API untuk mengambil informasi tentang akun Google Drive pengguna yang diberi otorisasi.

  5. Jika permintaan berhasil dieksekusi, respons API akan dicatat di konsol pen-debug browser.

Anda dapat mencabut akses ke aplikasi melalui halaman Izin untuk Akun Google Anda. Aplikasi akan dicantumkan sebagai OAuth 2.0 Demo for Google API Docs.

Untuk menjalankan kode ini secara lokal, Anda perlu menetapkan nilai untuk variabel YOUR_CLIENT_ID dan YOUR_REDIRECT_URI yang sesuai dengan kredensial otorisasi Anda. Variabel YOUR_REDIRECT_URI harus ditetapkan ke URL yang sama dengan tempat halaman ditayangkan. Nilai harus sama persis dengan salah satu URI pengalihan yang diberi otorisasi untuk klien OAuth 2.0, yang Anda konfigurasi di . Jika nilai ini tidak cocok dengan URI yang sah, Anda akan mendapatkan error redirect_uri_mismatch. Project Anda juga harus mengaktifkan API yang sesuai untuk permintaan ini.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var fragmentString = location.hash.substring(1);
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0 && params['state']) {
    if (params['state'] == localStorage.getItem('state')) {
      localStorage.setItem('oauth2-test-params', JSON.stringify(params) );

      trySampleRequest();
    } else {
      console.log('State mismatch. Possible CSRF attack');
    }
  }

  // Function to generate a random state value
  function generateCryptoRandomState() {
    const randomValues = new Uint32Array(2);
    window.crypto.getRandomValues(randomValues);

    // Encode as UTF-8
    const utf8Encoder = new TextEncoder();
    const utf8Array = utf8Encoder.encode(
      String.fromCharCode.apply(null, randomValues)
    );

    // Base64 encode the UTF-8 data
    return btoa(String.fromCharCode.apply(null, utf8Array))
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=+$/, '');
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) { 
      // User authorized the request. Now, check which scopes were granted.
      if (params['scope'].includes('https://www.googleapis.com/auth/drive.metadata.readonly')) {
        // User authorized read-only Drive activity permission.
        // Calling the APIs, etc.
        var xhr = new XMLHttpRequest();
        xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
        xhr.onreadystatechange = function (e) {
          if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(xhr.response);
          } else if (xhr.readyState === 4 && xhr.status === 401) {
            // Token invalid, so prompt for user permission.
            oauth2SignIn();
          }
        };
        xhr.send(null);
      }
      else {
        // User didn't authorize read-only Drive activity permission.
        // Update UX and application accordingly
        console.log('User did not authorize read-only Drive activity permission.');
      }

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

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // create random state value and store in local storage
    var state = generateCryptoRandomState();
    localStorage.setItem('state', state);

    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly',
                  'state': state,
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

Aturan validasi asal JavaScript

Google menerapkan aturan validasi berikut ke asal JavaScript untuk membantu developer menjaga keamanan aplikasi mereka. Asal JavaScript Anda harus mematuhi aturan ini. Lihat RFC 3986 bagian 3 untuk definisi domain, host, dan skema, yang disebutkan di bawah.

Aturan validasi
Skema

Asal JavaScript harus menggunakan skema HTTPS, bukan HTTP biasa. URI localhost (termasuk URI alamat IP localhost) dikecualikan dari aturan ini.

Host

Host tidak boleh berupa alamat IP mentah. Alamat IP localhost dikecualikan dari aturan ini.

Domain
  • TLD Host (Domain Level Teratas) harus termasuk dalam daftar akhiran publik.
  • Domain host tidak boleh “googleusercontent.com”.
  • Asal JavaScript tidak boleh berisi domain penyingkat URL (mis. goo.gl) kecuali jika aplikasi memiliki domain tersebut.
  • Userinfo

    Origin JavaScript tidak boleh berisi subkomponen info pengguna.

    Path

    Asal JavaScript tidak boleh berisi komponen jalur.

    Kueri

    Asal JavaScript tidak boleh berisi komponen kueri.

    Fragment

    Asal JavaScript tidak boleh berisi komponen fragmen.

    Karakter Asal JavaScript tidak boleh berisi karakter tertentu, termasuk:
    • Karakter pengganti ('*')
    • Karakter ASCII yang tidak dapat dicetak
    • Encoding persen tidak valid (encoding persen yang tidak mengikuti bentuk encoding URL dari tanda persen yang diikuti dengan dua digit heksadesimal)
    • Karakter null (karakter NULL yang dienkode, misalnya, %00, %C0%80)

    Otorisasi inkremental

    Dalam protokol OAuth 2.0, aplikasi Anda meminta otorisasi untuk mengakses resource, yang diidentifikasi oleh cakupan. Praktik terbaik pengalaman pengguna adalah meminta otorisasi untuk resource pada saat Anda membutuhkannya. Untuk mengaktifkan praktik tersebut, server otorisasi Google mendukung otorisasi inkremental. Fitur ini memungkinkan Anda meminta cakupan sesuai kebutuhan dan, jika pengguna memberikan izin untuk cakupan baru, akan menampilkan kode otorisasi yang dapat ditukar dengan token yang berisi semua cakupan yang telah diberikan pengguna kepada project.

    Misalnya, aplikasi yang memungkinkan orang mencicipi trek musik dan membuat campuran mungkin hanya memerlukan sedikit resource saat waktu login, mungkin hanya nama orang yang login. Namun, menyimpan mix yang telah selesai akan memerlukan akses ke Google Drive mereka. Sebagian besar orang akan merasa wajar jika mereka hanya diminta akses ke Google Drive mereka pada saat aplikasi benar-benar membutuhkannya.

    Dalam hal ini, saat login, aplikasi dapat meminta cakupan openid dan profile untuk melakukan login dasar, lalu meminta cakupan https://www.googleapis.com/auth/drive.file pada saat permintaan pertama untuk menyimpan campuran.

    Aturan berikut berlaku untuk token akses yang diperoleh dari otorisasi inkremental:

    • Token dapat digunakan untuk mengakses resource yang sesuai dengan cakupan yang digabungkan ke dalam otorisasi gabungan yang baru.
    • Saat Anda menggunakan token refresh untuk otorisasi gabungan guna mendapatkan token akses, token akses tersebut mewakili otorisasi gabungan dan dapat digunakan untuk nilai scope apa pun yang disertakan dalam respons.
    • Otorisasi gabungan mencakup semua cakupan yang diberikan pengguna ke project API meskipun jika pemberian tersebut diminta dari klien yang berbeda. Misalnya, jika pengguna memberikan akses ke satu cakupan menggunakan klien desktop aplikasi, lalu memberikan cakupan lain ke aplikasi yang sama melalui klien seluler, otorisasi gabungan akan mencakup kedua cakupan.
    • Jika Anda mencabut token yang merepresentasikan otorisasi gabungan, akses ke semua cakupan otorisasi tersebut atas nama pengguna terkait akan dicabut secara bersamaan.

    Contoh kode di bawah menunjukkan cara menambahkan cakupan ke token akses yang ada. Pendekatan ini memungkinkan aplikasi Anda tidak perlu mengelola beberapa token akses.

    Endpoint OAuth 2.0

    Untuk menambahkan cakupan ke token akses yang ada, sertakan parameter include_granted_scopes dalam permintaan Anda ke server OAuth 2.0 Google.

    Cuplikan kode berikut menunjukkan cara melakukannya. Cuplikan ini mengasumsikan bahwa Anda telah menyimpan cakupan yang valid untuk token akses Anda di penyimpanan lokal browser. (Kode contoh lengkap menyimpan daftar cakupan yang valid untuk token akses dengan menyetel properti oauth2-test-params.scope di penyimpanan lokal browser.)

    Cuplikan membandingkan cakupan yang valid untuk token akses dengan cakupan yang ingin Anda gunakan untuk kueri tertentu. Jika token akses tidak mencakup cakupan tersebut, alur OAuth 2.0 akan dimulai. Di sini, fungsi oauth2SignIn sama dengan fungsi yang disediakan di langkah 2 (dan yang disediakan nanti dalam contoh lengkap).

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    Pencabutan token

    Dalam beberapa kasus, pengguna mungkin ingin mencabut akses yang diberikan ke aplikasi. Pengguna dapat mencabut akses dengan membuka Setelan Akun. Lihat bagian Hapus akses situs atau aplikasi di dokumen dukungan Situs & aplikasi pihak ketiga yang memiliki akses ke akun Anda untuk mengetahui informasi selengkapnya.

    Aplikasi juga dapat mencabut akses yang diberikan kepadanya secara terprogram. Pencabutan akses secara terprogram penting dalam kasus saat pengguna berhenti berlangganan, menghapus aplikasi, atau resource API yang diperlukan oleh aplikasi telah berubah secara signifikan. Dengan kata lain, bagian dari proses penghapusan dapat mencakup permintaan API untuk memastikan izin yang sebelumnya diberikan ke aplikasi dihapus.

    Endpoint OAuth 2.0

    Untuk mencabut token secara terprogram, aplikasi Anda membuat permintaan ke https://oauth2.googleapis.com/revoke dan menyertakan token sebagai parameter:

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

    Token dapat berupa token akses atau token refresh. Jika token adalah token akses dan memiliki token refresh yang sesuai, token refresh juga akan dicabut.

    Jika pencabutan berhasil diproses, kode status HTTP respons adalah 200. Untuk kondisi error, kode status HTTP 400 ditampilkan bersama dengan kode error.

    Cuplikan JavaScript berikut menunjukkan cara mencabut token di JavaScript tanpa menggunakan Library Klien Google API untuk JavaScript. Karena endpoint OAuth 2.0 Google untuk mencabut token tidak mendukung Cross-origin Resource Sharing (CORS), kode membuat formulir dan mengirimkan formulir ke endpoint, bukan menggunakan metode XMLHttpRequest() untuk memposting permintaan.

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }

    Menerapkan Perlindungan Lintas Akun

    Langkah tambahan yang harus Anda lakukan untuk melindungi akun pengguna Anda adalah menerapkan Perlindungan Lintas Akun dengan menggunakan Layanan Perlindungan Lintas Akun Google. Layanan ini memungkinkan Anda berlangganan notifikasi peristiwa keamanan yang memberikan informasi kepada aplikasi Anda tentang perubahan besar pada akun pengguna. Kemudian, Anda dapat menggunakan informasi tersebut untuk mengambil tindakan, bergantung pada cara Anda memutuskan untuk merespons peristiwa.

    Beberapa contoh jenis peristiwa yang dikirim ke aplikasi Anda oleh Layanan Perlindungan Lintas Akun Google adalah:

    • 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

    Lihat halaman Melindungi akun pengguna dengan Perlindungan Lintas Akun untuk mengetahui informasi selengkapnya tentang cara menerapkan Perlindungan Lintas Akun dan daftar lengkap peristiwa yang tersedia.