Mulai Chrome 126, developer dapat mulai menjalankan uji coba origin untuk paket fitur Federated Credential Management API (FedCM) desktop yang memungkinkan beberapa kasus penggunaan Otorisasi. Paket ini terdiri dari Continuation API dan Parameters API, yang memungkinkan pengalaman seperti alur otorisasi OAuth yang melibatkan dialog izin yang disediakan penyedia identitas (IdP). Paket ini juga menyertakan perubahan lain seperti Fields API, Beberapa configURL, dan Label Akun Kustom. Mulai Chrome 126, kami juga memperkenalkan uji coba origin untuk Storage Access API (SAA) yang otomatis memberikan permintaan SAA jika pengguna berhasil login menggunakan FedCM sebelumnya.
Uji Coba Origin: Paket FedCM Continuation API
Paket FedCM Continuation API terdiri dari beberapa ekstensi FedCM:
API Lanjutan
Anda dapat melihat demo API di Glitch.
Continuation API memungkinkan endpoint pernyataan ID IdP untuk secara opsional menampilkan URL yang akan dirender oleh FedCM agar pengguna dapat melanjutkan alur login multi-langkah. Hal ini memungkinkan IdP meminta pengguna untuk memberikan izin pihak tepercaya (RP) melebihi yang mungkin dilakukan di UI FedCM yang sudah ada, seperti akses ke resource sisi server pengguna.
Biasanya, endpoint pernyataan ID menampilkan token yang diperlukan untuk autentikasi.
{
"token": "***********"
}
Namun, dengan Continuation API, endpoint pernyataan ID dapat menampilkan properti continue_on
yang menyertakan jalur absolut atau jalur relatif ke endpoint pernyataan ID.
{
// In the id_assertion_endpoint, instead of returning a typical
// "token" response, the IdP decides that it needs the user to
// continue on a pop-up window:
"continue_on": "/oauth/authorize?scope=..."
}
Segera setelah browser menerima respons continue_on
, jendela pop-up baru akan terbuka dan mengarahkan pengguna ke jalur yang ditentukan.
Setelah pengguna berinteraksi dengan halaman, misalnya memberikan izin lebih lanjut
untuk membagikan informasi tambahan kepada RP, halaman IdP dapat memanggil
IdentityProvider.resolve()
untuk me-resolve panggilan
navigator.credentials.get()
yang asli dan menampilkan token sebagai argumen.
document.getElementById('allow_btn').addEventListener('click', async () => {
let accessToken = await fetch('/generate_access_token.cgi');
// Closes the window and resolves the promise (that is still hanging
// in the relying party's renderer) with the value that is passed.
IdentityProvider.resolve(accessToken);
});
Selanjutnya, browser akan menutup pop-up itu sendiri dan menampilkan token ke pemanggil API.
Jika pengguna menolak permintaan, Anda dapat menutup jendela dengan memanggil
IdentityProvider.close()
.
IdentityProvider.close();
Jika karena alasan tertentu pengguna telah mengubah akunnya di pop-up (misalnya, IdP menawarkan fungsi "ganti pengguna", atau dalam kasus delegasi), panggilan resolve akan menggunakan argumen kedua opsional yang memungkinkan hal seperti:
IdentityProvider.resolve(token, {accountId: '1234');
Parameters API
Parameters API memungkinkan RP memberikan parameter tambahan ke endpoint pernyataan ID. Dengan Parameters API, RP dapat meneruskan parameter tambahan ke IdP guna meminta izin untuk resource di luar login dasar. Pengguna akan memberikan izin ini melalui alur UX yang dikontrol IdP yang diluncurkan melalui Continuation API.
Untuk menggunakan API, tambahkan parameter ke properti params
sebagai objek dalam
panggilan navigator.credentials.get()
.
let {token} = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
configURL: 'https://idp.example/fedcm.json',
// Key/value pairs that need to be passed from the
// RP to the IdP but that don't really play any role with
// the browser.
params: {
IDP_SPECIFIC_PARAM: '1',
foo: 'BAR',
ETC: 'MOAR',
scope: 'calendar.readonly photos.write',
}
},
}
});
Nama properti dalam objek params
diawali dengan param_
. Dalam
contoh di atas, properti params berisi IDP_SPECIFIC_PARAM
sebagai '1'
, foo
sebagai 'BAR'
, ETC
sebagai 'MOAR'
, dan scope
sebagai 'calendar.readonly photos.write'
.
Ini akan diterjemahkan sebagai
param_IDP_SPECIFIC_PARAM=1¶m_foo=BAR¶m_ETC=MOAR¶m_scope=calendar.readonly%20photos.write
dalam isi HTTP permintaan:
POST /fedcm_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false¶m_IDP_SPECIFIC_PARAM=1¶m_foo=BAR¶m_ETC=MOAR¶m_scope=calendar.readonly%20photos.write
Mendapatkan izin secara dinamis
Secara umum, bagi pengguna, akan lebih mudah untuk meminta izin saat diperlukan, bukan saat developer merasa paling mudah diterapkan. Misalnya, meminta izin untuk mengakses kamera saat pengguna akan mengambil foto lebih disarankan daripada meminta izin segera setelah pengguna membuka situs. Praktik yang sama berlaku untuk sumber daya server. Minta izin hanya jika diperlukan oleh pengguna. Tindakan ini disebut "otorisasi dinamis".
Untuk meminta otorisasi secara dinamis dengan FedCM, IdP dapat:
- Panggil
navigator.credentials.get()
dengan parameter wajib yang dapat dipahami IdP, sepertiscope
. - Endpoint pernyataan ID mengonfirmasi bahwa pengguna sudah login dan merespons dengan URL
continue_on
. - Browser akan membuka jendela pop-up dengan halaman izin IdP yang meminta izin tambahan yang cocok dengan cakupan yang diminta.
- Setelah diotorisasi melalui
IdentityProvider.resolve()
oleh IdP, jendela akan ditutup dan panggilannavigator.credentials.get()
asli RP akan mendapatkan token atau kode otorisasi yang relevan sehingga RP dapat menukarnya dengan token akses yang sesuai.
Fields API
Fields API memungkinkan RP mendeklarasikan atribut akun yang akan diminta dari IdP sehingga browser dapat merender UI pengungkapan yang tepat dalam dialog FedCM; IdP bertanggung jawab untuk menyertakan kolom yang diminta dalam token yang ditampilkan. Pertimbangkan permintaan ini "profil dasar" di OpenID Connect versus "cakupan" di OAuth.
Untuk menggunakan Fields API, tambahkan parameter ke properti fields
sebagai array dalam panggilan navigator.credentials.get()
. Untuk saat ini, kolom dapat berisi 'name'
, 'email'
,
dan 'picture'
, tetapi dapat diperluas untuk menyertakan nilai lainnya di
masa mendatang.
Permintaan dengan fields
akan terlihat seperti ini:
let { token } = await navigator.credentials.get({
identity: {
providers: [{
fields: ['name', 'email', 'picture'],
clientId: '1234',
configURL: 'https://idp.example/fedcm.json',
params: {
scope: 'drive.readonly calendar.readonly',
}
},
}
mediation: 'optional',
});
Permintaan HTTP ke endpoint pernyataan ID
menyertakan parameter fields
yang ditentukan RP, dengan parameter disclosure_text_shown
ditetapkan sebagai true
jika ini bukan pengguna yang kembali, dan kolom yang
diungkap oleh browser kepada pengguna dalam parameter disclosure_shown_for
:
POST /id_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=true&fields=email,name,picture&disclosure_shown_for=email,name,picture
Jika RP memerlukan akses ke data tambahan dari IdP, seperti akses ke
kalender, hal ini harus ditangani dengan parameter kustom seperti yang disebutkan di atas. IdP akan menampilkan URL continue_on
untuk meminta izin.
Jika fields
adalah array kosong, permintaan akan terlihat seperti ini:
let { token } = await navigator.credentials.get({
identity: {
providers: [{
fields: [],
clientId: '1234',
configURL: 'https://idp.example/fedcm.json',
params: {
scope: 'drive.readonly calendar.readonly',
}
},
}
mediation: 'optional',
});
Jika fields
adalah array kosong, agen pengguna akan melewati UI pengungkapan.
Hal ini terjadi meskipun respons dari endpoint
akun
tidak berisi client ID yang cocok dengan RP di approved_clients
.
Dalam hal ini, disclosure_text_shown
yang dikirim ke endpoint pernyataan
ID adalah
salah dalam isi HTTP:
POST /id_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false
Beberapa configURL
Beberapa configURL memungkinkan IdP
menampung beberapa file konfigurasi untuk IdP, dengan menentukan
accounts_endpoint
dan login_url
dalam file
yang dikenal yang sama
dengan file konfigurasi.
Jika accounts_endpoint
dan login_url
ditambahkan ke file well-known,
provider_urls
akan diabaikan sehingga IdP dapat mendukung beberapa file konfigurasi.
Jika tidak, provider_urls
akan terus berlaku sehingga kompatibel
dengan versi sebelumnya.
File well-known yang mendukung beberapa configURL dapat terlihat seperti ini:
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
Hal ini memungkinkan kita untuk:
- Mempertahankan kompatibilitas mundur dan maju dengan file terkenal yang sudah ada dan browser versi sebelumnya yang sudah di-deploy di dunia nyata.
- Memiliki jumlah file konfigurasi arbitrer—asalkan semuanya mengarah ke
accounts_endpoint
danlogin_url
yang sama. - Tidak ada peluang bagi entropi untuk ditambahkan ke permintaan pengambilan berkredensial
yang dibuat ke
accounts_endpoint
, karena entropi harus ditentukan di tingkat "well-known".
Mendukung beberapa configURL bersifat opsional dan implementasi FedCM yang ada dapat tetap sama.
Label Akun Kustom
Label Akun Kustom memungkinkan IdP
FedCM menganotasi akun sehingga RP dapat memfilternya dengan menentukan label dalam
file konfigurasi. Pemfilteran serupa dapat dilakukan menggunakan Domain Hint API dan Login Hint API dengan menentukannya dalam panggilan navigator.credentials.get()
, tetapi Label Akun Kustom dapat memfilter pengguna dengan menentukan file konfigurasi, yang sangat berguna saat beberapa configURL digunakan. Label Akun Kustom
juga berbeda karena disediakan dari server IdP, bukan dari
RP, seperti login atau petunjuk domain.
Contoh
IdP mendukung dua configURL masing-masing untuk konsumen dan perusahaan. File
konfigurasi konsumen memiliki label 'consumer'
, dan file konfigurasi perusahaan
memiliki label 'enterprise'
.
Dengan penyiapan seperti itu, file populer menyertakan accounts_endpoint
dan login_url
untuk mengizinkan beberapa configURL.
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
Jika accounts_endpoint
disediakan dalam file yang dikenal, provider_urls
akan diabaikan. RP dapat mengarah langsung ke file konfigurasi
masing-masing dalam panggilan navigator.credentials.get()
.
File konfigurasi konsumen berada di https://idp.example/fedcm.json
yang mencakup
properti accounts
yang menentukan 'consumer'
menggunakan include
.
{
"accounts_endpoint": "https://idp.example/accounts",
"client_metadata_endpoint": "/client_metadata",
"login_url": "https://idp.example/login",
"id_assertion_endpoint": "/assertion",
"accounts": {
"include": "consumer"
}
}
File konfigurasi perusahaan berada di https://idp.example/enterprise/fedcm.json
,
yang menyertakan properti accounts
yang menentukan 'enterprise'
menggunakan
include
.
{
"accounts_endpoint": "https://idp.example/accounts",
"client_metadata_endpoint": "/enterprise/client_metadata",
"login_url": "https://idp.example/login",
"id_assertion_endpoint": "/assertion",
"accounts": {
"include": "enterprise"
}
}
Endpoint akun IdP umum (dalam contoh ini https://idp.example/accounts
) menampilkan daftar akun yang menyertakan properti label dengan labels
yang ditetapkan dalam array untuk setiap akun.
Berikut adalah contoh respons untuk pengguna yang memiliki dua akun. Satu untuk konsumen dan satu lagi untuk perusahaan:
{
"accounts": [{
"id": "123",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
"labels": ["consumer"]
}], [{
"id": "4567",
"given_name": "Jane",
"name": "Jane Doe",
"email": "jane_doe@idp.example",
"picture": "https://idp.example/profile/4567",
"labels": ["enterprise"]
}]
}
Ketika RP ingin mengizinkan pengguna 'enterprise'
login, mereka dapat menentukan
'enterprise'
configURL 'https://idp.example/enterprise/fedcm.json'
dalam
panggilan navigator.credentials.get()
:
let { token } = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
nonce: '234234',
configURL: 'https://idp.example/enterprise/fedcm.json',
},
}
});
Akibatnya, hanya ID akun '4567'
yang tersedia bagi pengguna untuk login. ID akun '123'
disembunyikan secara diam-diam oleh browser sehingga pengguna
tidak akan diberi akun yang tidak didukung oleh IdP di situs ini.
Uji coba origin: FedCM sebagai sinyal kepercayaan untuk Storage Access API
Chrome 126 memulai uji coba origin FedCM sebagai sinyal kepercayaan untuk Storage Access API. Dengan perubahan ini, pemberian izin sebelumnya melalui FedCM menjadi alasan yang valid untuk menyetujui permintaan akses penyimpanan secara otomatis oleh Storage Access API.
Hal ini berguna saat iframe tersemat ingin mengakses resource yang dipersonalisasi: misalnya, jika idp.example disematkan di rp.example dan perlu menampilkan resource yang dipersonalisasi. Jika browser membatasi akses ke cookie pihak ketiga, meskipun pengguna login ke rp.example menggunakan idp.example dengan FedCM, iframe idp.example yang disematkan tidak akan dapat meminta resource yang dipersonalisasi karena permintaan tidak akan menyertakan cookie pihak ketiga.
Untuk mencapai hal ini, idp.example perlu mendapatkan izin akses penyimpanan melalui iframe yang disematkan di situs, dan ini hanya dapat diperoleh melalui permintaan izin.
Dengan FedCM sebagai sinyal kepercayaan untuk Storage Access API, pemeriksaan izin Storage Access API tidak hanya menerima pemberian izin yang diberikan oleh perintah akses penyimpanan, tetapi juga pemberian izin yang diberikan oleh perintah FedCM.
// In top-level rp.example:
// Ensure FedCM permission has been granted.
const cred = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/fedcm.json',
clientId: '123',
}],
},
mediation: 'optional',
});
// In an embedded IdP iframe:
// No user gesture is needed to call this, and the call will be auto-granted.
await document.requestStorageAccess();
// This returns `true`.
const hasAccess = await document.hasStorageAccess();
Setelah pengguna login dengan FedCM, izin akan diberikan secara otomatis selama autentikasi FedCM aktif. Ini berarti setelah pengguna terputus, permintaan izin akan menampilkan perintah.
Berpartisipasi dalam uji coba origin
Anda dapat mencoba paket FedCM Continuation API secara lokal dengan mengaktifkan tanda
Chrome
chrome://flags#fedcm-authz
di Chrome 126 atau yang lebih baru. Anda juga dapat mencoba FedCM
sebagai sinyal kepercayaan untuk Storage Access API secara lokal dengan mengaktifkan
#fedcm-with-storage-access-api
di Chrome 126 atau yang lebih baru.
Fitur ini juga tersedia sebagai uji coba origin. Uji coba origin memungkinkan Anda mencoba fitur baru dan memberikan masukan terkait kegunaan, kepraktisan, dan efektivitasnya. Untuk informasi selengkapnya, lihat Memulai uji coba origin.
Untuk mencoba uji coba origin paket FedCM Continuation API, buat dua token uji coba origin:
- Daftar untuk uji coba. Sematkan token ke origin IdP.
- Daftar ke uji coba origin dengan mencentang kotak pencocokan pihak ketiga. Ikuti petunjuk di Mendaftarkan uji coba origin pihak ketiga untuk RP guna menyematkan token untuk RP.
Jika Anda tertarik untuk mengaktifkan Continuation API beserta alur tombol, aktifkan juga uji coba asal Button Mode API:
- Mendaftar ke uji coba origin sebagai pihak ketiga. Ikuti petunjuk di Mendaftarkan uji coba origin pihak ketiga untuk RP guna menyematkan token untuk RP.
Untuk mencoba FedCM sebagai sinyal kepercayaan untuk uji coba origin Storage Access API:
- Daftar untuk uji coba origin. Sematkan token ke origin IdP.
Uji coba origin paket Continuation API dan FedCM sebagai sinyal kepercayaan untuk Uji coba origin Storage Access API tersedia dari Chrome 126.
Mendaftarkan uji coba origin pihak ketiga untuk RP
- Buka halaman pendaftaran uji coba origin.
- Klik tombol Daftar dan isi formulir untuk meminta token.
- Masukkan origin IdP sebagai Origin Web.
- Periksa Pencocokan pihak ketiga untuk memasukkan token dengan JavaScript di origin lain.
- Klik Kirim.
- Sematkan token yang diterbitkan di situs pihak ketiga.
Untuk menyematkan token di situs pihak ketiga, tambahkan kode berikut ke library JavaScript atau SDK IdP yang ditayangkan dari origin IdP.
const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);
Ganti TOKEN_GOES_HERE
dengan token Anda sendiri.