Autentikasi pengguna akhir untuk Cloud Run


Tutorial ini menunjukkan cara membuat layanan pemungutan suara yang terdiri dari:

  • Klien berbasis browser yang:

    1. Menggunakan Identity Platform untuk mengambil token ID.
    2. Memungkinkan pengguna untuk memilih hewan domestik favorit mereka.
    3. Menambahkan token ID untuk permintaan ke server Cloud Run yang memproses suara.
  • Server Cloud Run yang:

    1. Periksa untuk memastikan pengguna akhir sudah diautentikasi secara benar dengan memberikan token ID yang valid.
    2. Memproses suara pengguna akhir.
    3. Dengan menggunakan kredensialnya sendiri, mengirim suara ke Cloud SQL untuk disimpan.
  • Database PostgreSQL yang menyimpan suara.

Agar mudah, tutorial ini menggunakan Google sebagai penyedia: pengguna harus melakukan autentikasi menggunakan akun Google untuk mendapatkan token ID mereka. Namun, Anda dapat menggunakan penyedia atau metode autentikasi lain untuk memasukkan pengguna.

Layanan ini meminimalkan risiko keamanan dengan menggunakanSecret Manager untuk melindungi data sensitif yang digunakan untuk terhubung ke instance Cloud SQL. Opsi ini juga digunakan pada identity layanan dengan hak istimewa terendah untuk akses yang aman ke database.

Tujuan

Tulis, build, dan deploy ke Cloud Run yang menunjukkan cara:

  • Gunakan Identity Platform untuk mengautentikasi pengguna akhir ke backend layanan Cloud Run.

  • Buat identity hak istimewa terendah pada layanan untuk memberikan akses pada resource Google Cloud.

  • Gunakan Secret Manager untuk menangani data sensitif ketika dihubungkan dengan layanan Cloud Run ke database postgreSQL .

Biaya

Dalam dokumen ini, Anda menggunakan komponen Google Cloud yang dapat ditagih berikut:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga. Pengguna baru Google Cloud mungkin memenuhi syarat untuk mendapatkan uji coba gratis.

Sebelum memulai

  1. Login ke akun Google Cloud Anda. Jika Anda baru menggunakan Google Cloud, buat akun untuk mengevaluasi performa produk kami dalam skenario dunia nyata. Pelanggan baru juga mendapatkan kredit gratis senilai $300 untuk menjalankan, menguji, dan men-deploy workload.
  2. Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud.

    Buka pemilih project

  3. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  4. Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud.

    Buka pemilih project

  5. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  6. Aktifkan API Cloud Run, Secret Manager, Cloud SQL, Artifact Registry, and Cloud Build .

    Mengaktifkan API

Peran yang diperlukan

Guna mendapat izin yang Anda perlukan untuk menyelesaikan tutorial, minta administrator Anda untuk memberikan peran Pemilik (roles/owner) IAM role pada project Anda. Untuk mengetahui informasi selengkapnya tentang cara memberikan peran, lihat Kelola akses.

Anda mungkin juga bisa mendapatkan izin yang diperlukan melalui peran khusus atau peran bawaan lainnya.

Menyiapkan default gcloud

Untuk mengonfigurasi gcloud dengan setelan default untuk layanan Cloud Run Anda:

  1. Setel project default Anda:

    gcloud config set project PROJECT_ID

    Ganti PROJECT_ID dengan nama project yang Anda buat untuk tutorial ini.

  2. Konfigurasi gcloud untuk region yang Anda pilih:

    gcloud config set run/region REGION

    Ganti REGION dengan region Cloud Run pilihan Anda yang didukung.

Lokasi Cloud Run

Cloud Run bersifat regional, berarti infrastruktur yang menjalankan layanan Cloud Run Anda terletak di region tertentu dan dikelola oleh Google agar tersedia secara redundan di semua zona dalam region tersebut.

Memenuhi persyaratan latensi, ketersediaan, atau ketahanan adalah faktor utama untuk memilih region tempat layanan Cloud Run dijalankan. Pada umumnya, Anda dapat memilih region yang paling dekat dengan pengguna Anda, tetapi Anda harus mempertimbangkan lokasi dari produk Google Cloud lain yang digunakan oleh layanan Cloud Run Anda. Menggunakan produk Google Cloud secara bersamaan di beberapa lokasi dapat memengaruhi latensi serta biaya layanan Anda.

Cloud Run tersedia di region berikut:

Tergantung harga Tingkat 1

  • asia-east1 (Taiwan)
  • asia-northeast1 (Tokyo)
  • asia-northeast2 (Osaka)
  • europe-north1 (Finlandia) ikon daun CO2 Rendah
  • europe-southwest1 (Madrid)
  • europe-west1 (Belgia) ikon daun CO2 Rendah
  • europe-west4 (Belanda)
  • europe-west8 (Milan)
  • europe-west9 (Paris) ikon daun CO2 Rendah
  • me-west1 (Tel Aviv)
  • us-central1 (Iowa) ikon daun CO2 rendah
  • us-east1 (South Carolina)
  • us-east4 (North Virginia)
  • us-east5 (Columbus)
  • us-south1 (Dallas)
  • us-west1 (Oregon) ikon daun CO2 Rendah

Tergantung harga Tingkat 2

  • africa-south1 (Johannesburg)
  • asia-east2 (Hong Kong)
  • asia-northeast3 (Seoul, Korea Selatan)
  • asia-southeast1 (Singapura)
  • asia-southeast2 (Jakarta)
  • asia-south1 (Mumbai, India)
  • asia-south2 (Delhi, India)
  • australia-southeast1 (Sydney)
  • australia-southeast2 (Melbourne)
  • europe-central2 (Warsawa, Polandia)
  • europe-west10 (Berlin)
  • europe-west12 (Turin)
  • europe-west2 (London, Inggris Raya) ikon daun CO2 Rendah
  • europe-west3 (Frankfurt, Jerman) ikon daun CO2 Rendah
  • europe-west6 (Zurich, Swiss) ikon daun CO2 Rendah
  • me-central1 (Doha)
  • me-central2 (Damam)
  • northamerica-northeast1 (Montreal) ikon daun CO2 Rendah
  • northamerica-northeast2 (Toronto) ikon daun CO2 Rendah
  • southamerica-east1 (Sao Paulo, Brasil) ikon daun CO2 Rendah
  • southamerica-west1 (Santiago, Cile) ikon daun CO2 Rendah
  • us-west2 (Los Angeles)
  • us-west3 (Salt Lake City)
  • us-west4 (Las Vegas)

Jika sudah membuat layanan Cloud Run, Anda dapat melihat region di dasbor Cloud Run di Konsol Google Cloud.

Mengambil contoh kode

Untuk mengambil contoh kode agar dapat digunakan:

  1. Clone repositori aplikasi contoh ke komputer lokal Anda:

    Node.js

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

    Atau, Anda dapat mendownload sampel sebagai file ZIP dan mengekstraknya.

    Python

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

    Atau, Anda dapat mendownload sampel sebagai file ZIP dan mengekstraknya.

    Java

    git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git

    Atau, Anda dapat mendownload sampel sebagai file ZIP dan mengekstraknya.

  2. Ubah ke direktori yang memuat kode contoh Cloud Run:

    Node.js

    cd nodejs-docs-samples/run/idp-sql/

    Python

    cd python-docs-samples/run/idp-sql/

    Java

    cd java-docs-samples/run/idp-sql/

Memvisualisasikan arsitektur

Diagram Arsitektur
Diagram menunjukkan login pengguna akhir melalui pop up sign in Google yang disediakan Identity Platform, dan akan diarahkan kembali ke Cloud Run dengan menggunakan identitas pengguna.
  1. Pengguna akhir membuat permintaan pertama untuk server Cloud Run.

  2. Beban klien pada browser.

  3. Pengguna memberikan kredensial login melalui jendela pop up login Google dari Identity Platform. Pemberitahuan menyambut pengguna yang login.

  4. Kontrol dialihkan kembali ke server. Pengguna akhir memberi suara menggunakan klien, yang memberikan token ID dari Identity Platform dan menambahkannya pada header permintaan suara.

  5. Saat server menerima permintaan, server akan memverifikasi token ID Identity Platform, mengonfirmasi bahwa pengguna akhir telah diauntentikasi secara benar. Kemudian server mengirimkan suara ke Cloud SQL menggunakan kredensialnya sendiri.

Memahami kode inti

Contoh ini diimplementasikan sebagai klien dan server, seperti yang dijelaskan berikut.

Mengintegrasikan dengan Identity Platform: kode sisi klien

Contoh ini menggunakan Firebase SDKs untuk diintegrasikan dengan Identity Platform guna login dan mengelola pengguna. Untuk terhubung ke Identity Platform, JavaScript sisi klien menyimpan referensi ke kredensial project sebagai objek konfigurasi mengimpor Firebase JavaScript SDKsyang dibutuhkan:

const config = {
  apiKey: 'API_KEY',
  authDomain: 'PROJECT_ID.firebaseapp.com',
};
<!-- Firebase App (the core Firebase SDK) is always required and must be listed first-->
<script src="https://www.gstatic.com/firebasejs/7.18/firebase-app.js"></script>
<!-- Add Firebase Auth service-->
<script src="https://www.gstatic.com/firebasejs/7.18/firebase-auth.js"></script>

Firebase JavaScript SDK menangani alur login dengan meminta pengguna akhir login ke Akun Google mereka melalui jendela pop-up. Kemudian mereka akan diarahkan kembali ke layanan.

function signIn() {
  const provider = new firebase.auth.GoogleAuthProvider();
  provider.addScope('https://www.googleapis.com/auth/userinfo.email');
  firebase
    .auth()
    .signInWithPopup(provider)
    .then(result => {
      // Returns the signed in user along with the provider's credential
      console.log(`${result.user.displayName} logged in.`);
      window.alert(`Welcome ${result.user.displayName}!`);
    })
    .catch(err => {
      console.log(`Error during sign in: ${err.message}`);
      window.alert('Sign in failed. Retry or check your browser logs.');
    });
}

Saat pengguna berhasil login, klien akan menggunakan metode Firebase untuk membuat token ID. Klien menambahkan token ID ke Authorization header permintaannya ke server.

async function vote(team) {
  if (firebase.auth().currentUser) {
    // Retrieve JWT to identify the user to the Identity Platform service.
    // Returns the current token if it has not expired. Otherwise, this will
    // refresh the token and return a new one.
    try {
      const token = await firebase.auth().currentUser.getIdToken();
      const response = await fetch('/', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          Authorization: `Bearer ${token}`,
        },
        body: 'team=' + team, // send application data (vote)
      });
      if (response.ok) {
        const text = await response.text();
        window.alert(text);
        window.location.reload();
      }
    } catch (err) {
      console.log(`Error when submitting vote: ${err}`);
      window.alert('Something went wrong... Please try again!');
    }
  } else {
    window.alert('User not signed in.');
  }
}

Mengintegrasikan dengan Identity Platform: kode sisi server

Server menggunakan Firebase Admin SDK untuk memverifikasi token ID pengguna yang dikirim dari klien. Jika token ID yang diberikan memiliki format yang benar, masa berlakunya belum habis, dan ditandatangani dengan benar, metode tersebut akan menampilkan token ID yang didekode. Server mengekstrak Identity Platform uid untuk penggunanya.

Node.js

const firebase = require('firebase-admin');
// Initialize Firebase Admin SDK
firebase.initializeApp();

// Extract and verify Id Token from header
const authenticateJWT = (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (authHeader) {
    const token = authHeader.split(' ')[1];
    // If the provided ID token has the correct format, is not expired, and is
    // properly signed, the method returns the decoded ID token
    firebase
      .auth()
      .verifyIdToken(token)
      .then(decodedToken => {
        const uid = decodedToken.uid;
        req.uid = uid;
        next();
      })
      .catch(err => {
        req.logger.error(`Error with authentication: ${err}`);
        return res.sendStatus(403);
      });
  } else {
    return res.sendStatus(401);
  }
};

Python

def jwt_authenticated(func: Callable[..., int]) -> Callable[..., int]:
    """Use the Firebase Admin SDK to parse Authorization header to verify the
    user ID token.

    The server extracts the Identity Platform uid for that user.
    """

    @wraps(func)
    def decorated_function(*args: a, **kwargs: a) -> a:
        header = request.headers.get("Authorization", None)
        if header:
            token = header.split(" ")[1]
            try:
                decoded_token = firebase_admin.auth.verify_id_token(token)
            except Exception as e:
                logger.exception(e)
                return Response(status=403, response=f"Error with authentication: {e}")
        else:
            return Response(status=401)

        request.uid = decoded_token["uid"]
        return func(*args, **kwargs)

    return decorated_function

Java

/** Extract and verify Id Token from header */
private String authenticateJwt(Map<String, String> headers) {
  String authHeader =
      (headers.get("authorization") != null)
          ? headers.get("authorization")
          : headers.get("Authorization");
  if (authHeader != null) {
    String idToken = authHeader.split(" ")[1];
    // If the provided ID token has the correct format, is not expired, and is
    // properly signed, the method returns the decoded ID token
    try {
      FirebaseToken decodedToken = FirebaseAuth.getInstance().verifyIdToken(idToken);
      String uid = decodedToken.getUid();
      return uid;
    } catch (FirebaseAuthException e) {
      logger.error("Error with authentication: " + e.toString());
      throw new ResponseStatusException(HttpStatus.FORBIDDEN, "", e);
    }
  } else {
    logger.error("Error no authorization header");
    throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
  }
}

Menghubungkan server ke Cloud SQL

Server terhubung dengan soket domain Unix Instance Cloud SQL menggunakan format: /cloudsql/CLOUD_SQL_CONNECTION_NAME.

Node.js

/**
 * Connect to the Cloud SQL instance through UNIX Sockets
 *
 * @param {object} credConfig The Cloud SQL connection configuration from Secret Manager
 * @returns {object} Knex's PostgreSQL client
 */
const connectWithUnixSockets = async credConfig => {
  const dbSocketPath = process.env.DB_SOCKET_PATH || '/cloudsql';
  // Establish a connection to the database
  return Knex({
    client: 'pg',
    connection: {
      user: credConfig.DB_USER, // e.g. 'my-user'
      password: credConfig.DB_PASSWORD, // e.g. 'my-user-password'
      database: credConfig.DB_NAME, // e.g. 'my-database'
      host: `${dbSocketPath}/${credConfig.CLOUD_SQL_CONNECTION_NAME}`,
    },
    ...config,
  });
};

Python

def init_unix_connection_engine(
    db_config: dict[str, int]
) -> sqlalchemy.engine.base.Engine:
    """Initializes a Unix socket connection pool for a Cloud SQL instance of PostgreSQL.

    Args:
        db_config: a dictionary with connection pool config

    Returns:
        A SQLAlchemy Engine instance.
    """
    creds = credentials.get_cred_config()
    db_user = creds["DB_USER"]
    db_pass = creds["DB_PASSWORD"]
    db_name = creds["DB_NAME"]
    db_socket_dir = creds.get("DB_SOCKET_DIR", "/cloudsql")
    cloud_sql_connection_name = creds["CLOUD_SQL_CONNECTION_NAME"]

    pool = sqlalchemy.create_engine(
        # Equivalent URL:
        # postgres+pg8000://<db_user>:<db_pass>@/<db_name>
        #                         ?unix_sock=<socket_path>/<cloud_sql_instance_name>/.s.PGSQL.5432
        sqlalchemy.engine.url.URL.create(
            drivername="postgresql+pg8000",
            username=db_user,  # e.g. "my-database-user"
            password=db_pass,  # e.g. "my-database-password"
            database=db_name,  # e.g. "my-database-name"
            query={
                "unix_sock": f"{db_socket_dir}/{cloud_sql_connection_name}/.s.PGSQL.5432"
                # e.g. "/cloudsql", "<PROJECT-NAME>:<INSTANCE-REGION>:<INSTANCE-NAME>"
            },
        ),
        **db_config,
    )
    pool.dialect.description_encoding = None
    logger.info("Database engine initialized from unix connection")

    return pool

Java

Gunakan integrasi starter Spring Cloud Google Cloud PostgreSQL untuk berinteraksi dengan database PostgreSQL Anda di Google Cloud SQL menggunakan pustaka Spring JDBC. Setel konfigurasi Cloud SQL untuk MySQL ke konfigurasi bean DataSource secara otomatis, yang digabungkan dengan Spring JDBC, yang menyediakan JdbcTemplate objek bean yang memungkinkan untuk operasi seperti melakukan kueri dan perubahan pada database.

# Uncomment and add env vars for local development
# spring.datasource.username=${DB_USER}
# spring.datasource.password=${DB_PASSWORD}
# spring.cloud.gcp.sql.database-name=${DB_NAME}
# spring.cloud.gcp.sql.instance-connection-name=${CLOUD_SQL_CONNECTION_NAME}  
private final JdbcTemplate jdbcTemplate;

public VoteController(JdbcTemplate jdbcTemplate) {
  this.jdbcTemplate = jdbcTemplate;
}

Menangani konfigurasi sensitif dengan Secret Manager

Secret Manager menyediakan penyimpanan data sensitif yang terpusat dan aman, seperti konfigurasi Cloud SQL. Server memasukkan kredensial Cloud SQL dari Secret Manager saat runtime melalui variabel lingkungan. Pelajari lebih lanjut tentang Using Secret dengan Cloud Run.

Node.js

// CLOUD_SQL_CREDENTIALS_SECRET is the resource ID of the secret, passed in by environment variable.
// Format: projects/PROJECT_ID/secrets/SECRET_ID/versions/VERSION
const {CLOUD_SQL_CREDENTIALS_SECRET} = process.env;
if (CLOUD_SQL_CREDENTIALS_SECRET) {
  try {
    // Parse the secret that has been added as a JSON string
    // to retrieve database credentials
    return JSON.parse(CLOUD_SQL_CREDENTIALS_SECRET.toString('utf8'));
  } catch (err) {
    throw Error(
      `Unable to parse secret from Secret Manager. Make sure that the secret is JSON formatted: ${err}`
    );
  }
}

Python

def get_cred_config() -> dict[str, str]:
    """Retrieve Cloud SQL credentials stored in Secret Manager
    or default to environment variables.

    Returns:
        A dictionary with Cloud SQL credential values
    """
    secret = os.environ.get("CLOUD_SQL_CREDENTIALS_SECRET")
    if secret:
        return json.loads(secret)

Java

/** Retrieve config from Secret Manager */
public static HashMap<String, Object> getConfig() {
  String secret = System.getenv("CLOUD_SQL_CREDENTIALS_SECRET");
  if (secret == null) {
    throw new IllegalStateException("\"CLOUD_SQL_CREDENTIALS_SECRET\" is required.");
  }
  try {
    HashMap<String, Object> config = new Gson().fromJson(secret, HashMap.class);
    return config;
  } catch (JsonSyntaxException e) {
    logger.error(
        "Unable to parse secret from Secret Manager. Make sure that it is JSON formatted: "
            + e);
    throw new RuntimeException(
        "Unable to parse secret from Secret Manager. Make sure that it is JSON formatted.");
  }
}

Menyiapkan Identity Platform

Identity Platform memerlukan penyiapan manual di Konsol Google Cloud.

  1. Buka halaman Identity Platform Marketplace di Konsol Google Cloud.

    Buka halaman Identity Platform Marketplace

  2. Klik Aktifkan Identity Platform.

  3. Buat Layar persetujuan OAuth Anda:

    1. Di jendela baru, buka halaman API & Layanan > Kredensial

      Buka halaman APIs & Services > Credentials

    2. Klik Konfigurasi Layar Persetujuan.

    3. Untuk tujuan pengujian, pilih Eksternal.

    4. Klik Create.

    5. Dalam dialog Informasi aplikasi,

      1. Berikan nama aplikasi.
      2. Pilih salah satu email dukungan pengguna yang ditampilkan.
      3. Masukkan email yang ingin Anda gunakan untuk kontak developer.
    6. Klik Simpan dan Lanjutkan.

    7. Pada dialog Cakupan dan Pengguna Uji, klik Simpan dan Lanjutkan.

    8. Klik Kembali ke Dasbor.

    9. Di bagian Status publikasi, klik Publikasikan Aplikasi.

    10. Klik Konfirmasi.

  4. Buat serta dapatkan Secret dan Client ID Klien OAuth Anda:

    1. Buka halaman APIs & Services > Credentials

    2. Di bagian atas halaman, klik Buat Kredensial dan pilih OAuth client ID.

    3. Dari Jenis Aplikasi, pilih Aplikasi Web, dan beri nama.

    4. Perhatikan client_id dan client_secret untuk digunakan nanti dalam prosedur ini.

  5. Konfigurasi Google sebagai penyedia:

    1. Buka halaman Penyedia Identitas di Cloud Console.

      Buka halaman Penyedia Identitas

    2. Klik Tambahkan Penyedia.

    3. Pilih Google dari daftar.

    4. Di setelan Konfigurasi Web SDK, masukkan nilai client_id dan client_secret dari langkah sebelumnya.

    5. Di bagian bawah Konfigurasi aplikasi Anda, klik Detail Penyiapan.

    6. Salin nilai apiKey dan authDomain ke dalam contoh static/config.js untuk melakukan inisialisasi SDK Klien Identity Platform.

    7. Klik Save.

Men-deploy layanan

Ikuti langkah-langkah di bawah ini untuk menyelesaikan penyediaan dan deployment infrastruktur atau mengotomatisasi proses di Cloud Shell dengan mengklik "Jalankan di Google Cloud":

Menjalankan di Google Cloud

  1. Buat instance Cloud SQL dengan database postgreSQL menggunakan Konsol atau CLI:

    gcloud sql instances create CLOUD_SQL_INSTANCE_NAME \
        --database-version=POSTGRES_12 \
        --region=CLOUD_SQL_REGION \
        --cpu=2 \
        --memory=7680MB \
        --root-password=DB_PASSWORD
  2. Tambahkan nilai kredensial Cloud SQL Anda ke postgres-secrets.json:

    Node.js

    {
      "CLOUD_SQL_CONNECTION_NAME": "PROJECT_ID:REGION:INSTANCE",
      "DB_NAME": "postgres",
      "DB_USER": "postgres",
      "DB_PASSWORD": "PASSWORD_SECRET"
    }
    

    Python

    {
      "CLOUD_SQL_CONNECTION_NAME": "PROJECT_ID:REGION:INSTANCE",
      "DB_NAME": "postgres",
      "DB_USER": "postgres",
      "DB_PASSWORD": "PASSWORD_SECRET"
    }
    

    Java

    {
      "spring.cloud.gcp.sql.instance-connection-name": "PROJECT_ID:REGION:INSTANCE",
      "spring.cloud.gcp.sql.database-name": "postgres",
      "spring.datasource.username": "postgres",
      "spring.datasource.password": "PASSWORD_SECRET"
    }

  3. Buat secret yang diberi versi menggunakan Konsol atau CLI:

    gcloud secrets create idp-sql-secrets \
        --replication-policy="automatic" \
        --data-file=postgres-secrets.json
  4. Buat akun layanan untuk server menggunakan Konsol atau CLI:

    gcloud iam service-accounts create idp-sql-identity
  5. Berikan peran untuk akses Secret Manager dan Cloud SQL menggunakan Konsol atau CLI:

    1. Izinkan akun layanan yang terkait dengan server mengakses secret yang dibuat:

      gcloud secrets add-iam-policy-binding idp-sql-secrets \
        --member serviceAccount:idp-sql-identity@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/secretmanager.secretAccessor
    2. Izinkan akun layanan yang terkait dengan server untuk mengakses Cloud SQL:

      gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:idp-sql-identity@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/cloudsql.client
  6. Buat Artifact Registry:

    gcloud artifacts repositories create REPOSITORY \
        --repository-format docker \
        --location REGION
    • REPOSITORY adalah nama repositori. Untuk setiap lokasi repositori dalam project, nama repositori harus unik.
  7. Build image container menggunakan Cloud Build:

    Node.js

    gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/idp-sql

    Python

    gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/idp-sql

    Java

    Contoh ini menggunakan Jib untuk mem-build image Docker menggunakan alat Java umum. Jib mengoptimalkan build container tanpa memerlukan Dockerfile atau menginstal Docker. Pelajari lebih lanjut cara mem-build container Java dengan Jib.

    1. Gunakan gcloud credential helper untuk mengizinkan Docker mengirim ke Artifact Registry.

      gcloud auth configure-docker

    2. Gunakan Plugin Jib Maven untuk membangun dan mengirim container ke Artifact Registry.

      mvn compile jib:build -Dimage=REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/idp-sql

  8. Deploy image container ke Cloud Run menggunakan Konsol atau CLI. Perlu diingat bahwa server di-deploy untuk mengizinkan akses yang tidak diautentikasi. Hal ini dilakukan agar pengguna dapat memuat klien dan memulai prosesnya. Server memverifikasi token ID yang ditambahkan ke permintaan suara secara manual, sehingga mengautentikasi pengguna akhir.

    gcloud run deploy idp-sql \
        --image REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/idp-sql \
        --allow-unauthenticated \
        --service-account idp-sql-identity@PROJECT_ID.iam.gserviceaccount.com \
        --add-cloudsql-instances PROJECT_ID:REGION:CLOUD_SQL_INSTANCE_NAME \
        --update-secrets CLOUD_SQL_CREDENTIALS_SECRET=idp-sql-secrets:latest

    Perhatikan juga penanda,--service-account, --add-cloudsql-instances, dan --update-secrets , yang menentukan identitas layanan, koneksi instance Cloud SQL, dan nama secret dengan versi sebagai variabel lingkungan, yang tidak responsif.

Sentuhan akhir

Identity Platform mengharuskan Anda melakukan otorisasi URL layanan Cloud Run sebagai pengalihan yang diizinkan setelah pengguna login:

  1. Edit penyedia Google dengan mengklik ikon pena di halaman Penyedia Identitas.

  2. Klik Add Domain di bagian Authorized Domains di panel kanan, dan masukkan URL layanan Cloud Run.

    Anda dapat menemukan URL layanan di log setelah buil atau deployment, atau Anda dapat menemukannya kapan saja menggunakan:

    gcloud run services describe idp-sql --format 'value(status.url)'
  3. Buka halaman APIs & Services > Credentials

    1. Klik ikon pensil di samping Client ID OAuth Anda untuk mengeditnya, lalu di bawah tombol Authorized redirect URIs click the Add URI.

    2. Dalam kolom, salin dan tempel URL berikut, lalu klik tombol Simpan di bagian bawah halaman.

    https://PROJECT_ID.firebaseapp.com/__/auth/handler

Melakukan Percobaan

Untuk mencoba layanan lengkap:

  1. Buka browser Anda ke URL yang diberikan pada langkah deployment di atas.

  2. Klik tombol Login dengan Google dan ikuti alur autentikasi.

  3. Tambahkan suara Anda!

    Kodenya akan terlihat seperti berikut:

    Screenshot Antarmuka Pengguna menampilkan jumlah suara untuk setiap tim dan daftar suara.

Jika Anda memilih untuk terus mengembangkan layanan ini, perlu diingat bahwa layanan tersebut telah membatasi akses Identity and Access Management (IAM) ke bagian lain dari Google Cloud dan perlu diberi peran IAM tambahan guna mengakses banyak layanan lainnya.

Pembersihan

Jika Anda membuat project baru untuk tutorial ini, hapus project tersebut. Jika Anda menggunakan project yang ada dan ingin mempertahankannya tanpa ada perubahan yang ditambahkan dalam tutorial ini, hapus resource yang dibuat untuk tutorial.

Menghapus project

Cara termudah untuk menghilangkan penagihan adalah dengan menghapus project yang Anda buat untuk tutorial.

Untuk menghapus project:

  1. Di konsol Google Cloud, buka halaman Manage resource.

    Buka Manage resource

  2. Pada daftar project, pilih project yang ingin Anda hapus, lalu klik Delete.
  3. Pada dialog, ketik project ID, lalu klik Shut down untuk menghapus project.

Menghapus resource tutorial

  1. Hapus layanan Cloud Run yang Anda deploy dalam tutorial ini:

    gcloud run services delete SERVICE-NAME

    Dengan SERVICE-NAME adalah nama layanan pilihan Anda.

    Anda juga dapat menghapus layanan Cloud Run dari Konsol Google Cloud.

  2. Hapus konfigurasi region default gcloud yang Anda tambahkan selama penyiapan tutorial:

     gcloud config unset run/region
    
  3. Hapus konfigurasi project:

     gcloud config unset project
    
  4. Hapus resource Google Cloud lain yang dibuat dalam tutorial ini:

Langkah berikutnya