Login dengan Google untuk aplikasi sisi server

Untuk menggunakan layanan Google atas nama pengguna saat pengguna sedang offline, Anda harus menggunakan alur sisi server campuran tempat pengguna memberikan otorisasi ke aplikasi Anda di klien menggunakan klien JavaScript API dan Anda mengirim email khusus kode otorisasi ke server Anda. Server Anda menukar layanan sekali pakai ini kode tertentu untuk memperoleh aksesnya sendiri dan memperbarui token dari Google agar server dapat dapat melakukan panggilan API sendiri, yang dapat dilakukan saat pengguna sedang offline. Alur kode sekali pakai ini memiliki keunggulan keamanan dibandingkan sisi server murni mengalir dan mengirim token akses ke server Anda.

Alur login untuk mendapatkan token akses bagi sisi server Anda diilustrasikan di bawah ini.

Kode sekali pakai memiliki beberapa keunggulan keamanan. Dengan kode, Google menyediakan token langsung ke server Anda tanpa perantara. Meskipun kami tidak menyarankan untuk membocorkan kode, namun kode ini sangat sulit digunakan tanpa rahasia klien Anda. Jaga rahasia klien Anda.

Mengimplementasikan alur kode sekali pakai

Tombol Login dengan Google memberikan token akses dan kode otorisasi. Kode tersebut adalah kode sekali pakai yang dapat ditukarkan oleh server Anda dengan server Google untuk token akses.

Kode contoh berikut menunjukkan cara melakukan alur kode satu kali.

Mengautentikasi Login dengan Google dengan alur kode satu kali mengharuskan Anda untuk:

Langkah 1: Membuat client ID dan rahasia klien

Untuk membuat client ID dan rahasia klien, buat project Konsol API Google, menyiapkan client ID OAuth, dan mendaftarkan origin JavaScript Anda:

  1. Buka Konsol Google API.

  2. Dari drop-down project, pilih project yang sudah ada, atau buat yang baru dengan memilih Create a new project.

  3. Di sidebar di bagian "API & Services", pilih Credentials, lalu klik Konfigurasi layar izin.

    Pilih Alamat Email, tentukan Nama Produk, lalu tekan Simpan.

  4. Di tab Credentials, pilih drop-down Create credentials dan pilih OAuth client ID.

  5. Di bagian Application type, pilih Web application.

    Daftarkan origin tempat aplikasi Anda diizinkan untuk mengakses Google API, sebagai berikut. Origin adalah kombinasi unik dari protokol, nama {i>host<i}, dan porta.

    1. Di kolom Asal JavaScript yang sah, masukkan origin untuk aplikasi Anda. Anda dapat memasukkan beberapa origin agar aplikasi dapat berjalan di protokol, domain, atau subdomain yang berbeda. Anda tidak dapat menggunakan karakter pengganti. Pada contoh di bawah, URL kedua dapat berupa URL produksi.

      http://localhost:8080
      https://myproductionurl.example.com
      
    2. Kolom Authorized redirect URI tidak memerlukan nilai. Mengalihkan URI tidak digunakan dengan JavaScript API.

    3. Tekan tombol Buat.

  6. Dari kotak dialog Klien OAuth yang dihasilkan, salin Client-ID. Tujuan Client ID memungkinkan aplikasi Anda mengakses Google API yang diaktifkan.

Langkah 2: Sertakan library platform Google di halaman Anda

Sertakan skrip berikut yang menunjukkan fungsi anonim yang menyisipkan skrip ke dalam DOM halaman web index.html ini.

<!-- The top of file index.html -->
<html itemscope itemtype="http://schema.org/Article">
<head>
  <!-- BEGIN Pre-requisites -->
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">
  </script>
  <script src="https://apis.google.com/js/client:platform.js?onload=start" async defer>
  </script>
  <!-- END Pre-requisites -->

Langkah 3: Melakukan inisialisasi objek GoogleAuth

Muat library auth2 dan panggil gapi.auth2.init() untuk melakukan inisialisasi pada Objek GoogleAuth. Tentukan client ID dan cakupan yang ingin Anda minta saat Anda memanggil init().

<!-- Continuing the <head> section -->
  <script>
    function start() {
      gapi.load('auth2', function() {
        auth2 = gapi.auth2.init({
          client_id: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
          // Scopes to request in addition to 'profile' and 'email'
          //scope: 'additional_scope'
        });
      });
    }
  </script>
</head>
<body>
  <!-- ... -->
</body>
</html>

Langkah 4: Tambahkan tombol login ke halaman Anda

Tambahkan tombol login ke halaman web Anda, dan tambahkan pengendali klik untuk memanggil grantOfflineAccess() untuk memulai alur {i>one-time-code<i}.

<!-- Add where you want your sign-in button to render -->
<!-- Use an image that follows the branding guidelines in a real app -->
<button id="signinButton">Sign in with Google</button>
<script>
  $('#signinButton').click(function() {
    // signInCallback defined in step 6.
    auth2.grantOfflineAccess().then(signInCallback);
  });
</script>

Langkah 5: Buat pengguna login

Pengguna mengklik tombol login dan memberikan aplikasi Anda akses ke izin yang Anda minta. Selanjutnya, fungsi callback yang Anda tetapkan di Metode grantOfflineAccess().then() menerima objek JSON dengan kode otorisasi Anda. Contoh:

{"code":"4/yU4cQZTMnnMtetyFcIWNItG32eKxxxgXXX-Z4yyJJJo.4qHskT-UtugceFc0ZRONyF4z7U4UmAI"}

Langkah 6: Kirim kode otorisasi ke server

code adalah kode sekali pakai Anda yang dapat ditukarkan dengan server Anda sendiri token akses, dan token refresh. Anda hanya bisa mendapatkan token refresh setelah pengguna melihat dialog otorisasi yang meminta akses offline. Jika Anda telah menentukan select-account prompt di OfflineAccessOptions di langkah 4, Anda harus menyimpan token penyegaran yang Anda ambil untuk digunakan nanti karena bursa berikutnya akan menampilkan null untuk token refresh. Alur ini memberikan peningkatan keamanan melalui alur OAuth 2.0 standar Anda.

Token akses selalu dikembalikan dengan pertukaran otorisasi yang valid pada kode sumber.

Skrip berikut menentukan fungsi callback untuk tombol login. Kapan berhasil, fungsi tersebut menyimpan token akses untuk sisi klien, digunakan dan mengirimkan kode sekali sekali ke server Anda di domain yang sama.

<!-- Last part of BODY element in file index.html -->
<script>
function signInCallback(authResult) {
  if (authResult['code']) {

    // Hide the sign-in button now that the user is authorized, for example:
    $('#signinButton').attr('style', 'display: none');

    // Send the code to the server
    $.ajax({
      type: 'POST',
      url: 'http://example.com/storeauthcode',
      // Always include an `X-Requested-With` header in every AJAX request,
      // to protect against CSRF attacks.
      headers: {
        'X-Requested-With': 'XMLHttpRequest'
      },
      contentType: 'application/octet-stream; charset=utf-8',
      success: function(result) {
        // Handle or verify the server response.
      },
      processData: false,
      data: authResult['code']
    });
  } else {
    // There was an error.
  }
}
</script>

Langkah 7: Tukarkan kode otorisasi dengan token akses

Di server, tukar kode autentikasi dengan akses dan token refresh. Gunakan token akses untuk memanggil Google API atas nama pengguna dan, jika perlu, menyimpan token refresh untuk memperoleh token akses baru saat token akses tersebut sudah tidak berlaku.

Jika Anda meminta akses profil, Anda juga akan mendapatkan token ID yang berisi data informasi profil bagi pengguna.

Contoh:

Java
// (Receive authCode via HTTPS POST)


if (request.getHeader("X-Requested-With") == null) {
  // Without the `X-Requested-With` header, this request could be forged. Aborts.
}

// Set path to the Web application client_secret_*.json file you downloaded from the
// Google API Console: https://console.cloud.google.com/apis/credentials
// You can also find your Web application client ID and client secret from the
// console and specify them directly when you create the GoogleAuthorizationCodeTokenRequest
// object.
String CLIENT_SECRET_FILE = "/path/to/client_secret.json";

// Exchange auth code for access token
GoogleClientSecrets clientSecrets =
    GoogleClientSecrets.load(
        JacksonFactory.getDefaultInstance(), new FileReader(CLIENT_SECRET_FILE));
GoogleTokenResponse tokenResponse =
          new GoogleAuthorizationCodeTokenRequest(
              new NetHttpTransport(),
              JacksonFactory.getDefaultInstance(),
              "https://oauth2.googleapis.com/token",
              clientSecrets.getDetails().getClientId(),
              clientSecrets.getDetails().getClientSecret(),
              authCode,
              REDIRECT_URI)  // Specify the same redirect URI that you use with your web
                             // app. If you don't have a web version of your app, you can
                             // specify an empty string.
              .execute();

String accessToken = tokenResponse.getAccessToken();

// Use access token to call API
GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
Drive drive =
    new Drive.Builder(new NetHttpTransport(), JacksonFactory.getDefaultInstance(), credential)
        .setApplicationName("Auth Code Exchange Demo")
        .build();
File file = drive.files().get("appfolder").execute();

// Get profile info from ID token
GoogleIdToken idToken = tokenResponse.parseIdToken();
GoogleIdToken.Payload payload = idToken.getPayload();
String userId = payload.getSubject();  // Use this value as a key to identify a user.
String email = payload.getEmail();
boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
String name = (String) payload.get("name");
String pictureUrl = (String) payload.get("picture");
String locale = (String) payload.get("locale");
String familyName = (String) payload.get("family_name");
String givenName = (String) payload.get("given_name");
Python
from apiclient import discovery
import httplib2
from oauth2client import client

# (Receive auth_code by HTTPS POST)


# If this request does not have `X-Requested-With` header, this could be a CSRF
if not request.headers.get('X-Requested-With'):
    abort(403)

# Set path to the Web application client_secret_*.json file you downloaded from the
# Google API Console: https://console.cloud.google.com/apis/credentials
CLIENT_SECRET_FILE = '/path/to/client_secret.json'

# Exchange auth code for access token, refresh token, and ID token
credentials = client.credentials_from_clientsecrets_and_code(
    CLIENT_SECRET_FILE,
    ['https://www.googleapis.com/auth/drive.appdata', 'profile', 'email'],
    auth_code)

# Call Google API
http_auth = credentials.authorize(httplib2.Http())
drive_service = discovery.build('drive', 'v3', http=http_auth)
appfolder = drive_service.files().get(fileId='appfolder').execute()

# Get profile info from ID token
userid = credentials.id_token['sub']
email = credentials.id_token['email']