Petunjuk dan cakupan
Ini adalah masalah protokol OAuth dan perancangan keamanan. RFC 8628 ditujukan untuk smart TV, konsol media, printer, dan perangkat serupa yang tidak dapat memasukkan teks dengan mudah atau menjalankan peramban. Perangkat meminta device_code dan user_code; pengguna masuk dan mengotorisasi pada peramban terpisah; perangkat asli melakukan polling ke endpoint token. Perangkat seperti itu biasanya merupakan public client dan tidak dapat menyembunyikan client secret jangka panjang di dalam firmware. Latihan ini tidak menggantikan authorization-code flow untuk aplikasi native yang dapat menggunakan peramban sistem.
Hal yang diuji oleh pewawancara
- Membedakan masa berlaku device code, user code, URI verifikasi, access token, dan refresh token.
- Memetakan
authorization_pending,slow_down,expired_token, danaccess_deniedke state. - Merancang polling berbatas, backoff, idempoten, dan perlindungan konkurensi.
- Mengenali phishing user code, peniruan perangkat, tebakan brute-force, dan risiko public-client.
Klarifikasi yang perlu ditanyakan terlebih dahulu
Konfirmasikan apakah perangkat dapat menampilkan URI dan kode, membuat permintaan HTTPS, dan menjaga jam yang andal, serta apakah server otorisasi mendukung proses masuk OIDC. Perjelas sumber daya yang diminta, pengikatan perangkat, siapa yang menetapkan masa berlaku kode dan interval polling, serta apakah pembatalan diperlukan. Jika perangkat sudah memiliki peramban sistem, prioritaskan authorization-code flow RFC 8252 daripada memaksakan Device Flow.
Jawaban 30 detik
Terapkan dua endpoint. Endpoint otorisasi perangkat mengembalikan device_code berumur pendek, user_code yang dimasukkan manusia, verification_uri, masa kedaluwarsa, dan interval minimum. Endpoint token hanya menerima device code dan mengembalikan token atau error standar. Simpan hash dari device code, status, klien, dan masa kedaluwarsa. Lakukan polling pada interval yang disediakan server: lanjutkan pada authorization_pending, tingkatkan interval pada slow_down, dan hentikan saat berhasil, kedaluwarsa, penolakan, atau ketidakvalidan permanen. Tampilkan informasi perangkat di halaman pengguna untuk mengurangi phishing.
Solusi langkah demi langkah
1. Memodelkan partisipan dan satu sesi otorisasi
Partisipan mencakup perangkat terbatas, server otorisasi, peramban pengguna, dan server sumber daya. Endpoint otorisasi perangkat membuat sesi dengan device_code berentropi tinggi, user_code yang mudah dimasukkan, klien, scope yang diminta, waktu pembuatan, masa kedaluwarsa, dan status polling. Simpan hanya one-way digest dari device code sehingga pembacaan database tidak langsung menerbitkan token; indeks user code secara terpisah dan batasi percobaan.
2. Merancang respons otorisasi perangkat
Kembalikan setidaknya device_code, user_code, verification_uri, expires_in, dan interval. verification_uri_complete dapat menawarkan tautan yang praktis, tetapi tetap tampilkan kode pendek yang sama di perangkat dan halaman pengguna serta minta pengguna untuk mengonfirmasi perangkat di depan mereka. Lindungi kode dari log, analitik, dan tangkapan layar. Server tidak boleh menyertakan access token dalam respons ini.
3. Menangani interaksi dan pengikatan pengguna
Setelah membuka URI verifikasi, pengguna masuk dan melihat nama klien, scope yang diminta, serta informasi perangkat. Halaman persetujuan harus membuat pengguna mengonfirmasi bahwa perangkat tersebut adalah milik mereka, sehingga mengurangi otorisasi perangkat penyerang. Persetujuan mengubah sesi menjadi AUTHORIZED; ini tidak mengirimkan token melalui peramban ke perangkat. Penolakan adalah status terminal DENIED yang dilaporkan secara eksplisit oleh polling berikutnya.
4. Menentukan state machine endpoint token
Endpoint token menggerakkan status perangkat dengan error standar:
poll(device_code):
session = lookup(hash(device_code))
if session is missing: return invalid_grant
if now >= session.expiresAt: return expired_token
if session.status == DENIED: return access_denied
if session.status != AUTHORIZED: return authorization_pending
atomically mark CONSUMED
return issueAccessAndRefreshTokens(session)Penebusan satu device code yang berhasil harus bersifat atomik sehingga dua thread perangkat tidak dapat menerima dua set token. Jika kode hanya untuk sekali pakai, permintaan berulang akan mengembalikan invalid_grant atau error yang menunjukkan kode telah digunakan dari protokol; percobaan ulang yang gagal tidak boleh membuat sesi otorisasi baru.
5. Menerapkan backoff polling dan perlindungan server
Perangkat tidak boleh melakukan polling lebih cepat dari interval dalam respons. Pertahankan interval tersebut setelah authorization_pending; setelah slow_down, tingkatkan setidaknya 5 detik. Tambahkan batas waktu total, batas waktu jaringan, dan jitter pada perangkat. Terapkan rate limit berdasarkan device code, klien, dan IP di server. Respons token harus melarang caching agar perantara tidak memutar ulang status; selama beban tinggi, kembalikan error yang dapat dicoba lagi daripada membuat tugas latar belakang yang mahal untuk setiap polling.
6. Menangani kedaluwarsa, pembatalan, dan pemulihan
Perlakukan expired_token, access_denied, dan invalid_grant permanen sebagai status terminal. Hapus device code lokal dan hentikan polling. Tindakan pembatalan pada perangkat menandai sesi sebagai CANCELLED; permintaan selanjutnya tidak dapat menghidupkannya kembali. Saat terjadi gangguan jaringan, pertahankan batas waktu dan lanjutkan kode yang sama daripada membuat beberapa sesi yang dapat mengotorisasi perangkat yang salah. Setelah reboot, mulai ulang dan beri tahu pengguna jika perangkat tidak dapat mempertahankan status sesi secara aman.
7. Mengamankan public client dan menangkal phishing
Asumsikan perangkat tidak dapat melindungi client secret. Minimalkan scope, serta putar (rotate) dan cabut (revoke) refresh token. Buat user code cukup pendek untuk dimasukkan tetapi cukup acak untuk menahan tebakan online; batasi tingkat percobaan yang gagal berdasarkan kode dan IP. Tampilkan nama perangkat, model, atau kode sekali pakai dan minta pengguna untuk mencocokkannya dengan layar. Log hanya berisi ID sesi, hasil, dan pengidentifikasi yang di-hash, tidak pernah berisi device code mentah atau token.
8. Melakukan instrumentasi dan menguji alur
Ukur pembuatan otorisasi perangkat, penyelesaian, waktu hingga selesai, polling per sesi, tingkat slow_down, kedaluwarsa dan penolakan, serta race condition pada penebusan token. Uji penebusan duplikat, batas waktu, pergeseran jam, percobaan ulang jaringan, tebakan, polling serentak, penolakan pengguna, restart server, dan throttling. Pengujian menyeluruh (end-to-end) harus membuktikan bahwa perangkat yang disetujui dan sesi token akhir cocok; dua endpoint yang mengembalikan 200 secara independen tidaklah cukup.
Jawaban model
Saya akan membuat sesi RFC 8628 sekali pakai. Endpoint perangkat mengembalikan device_code berentropi tinggi, user code pendek, URI verifikasi, masa kedaluwarsa, dan interval polling minimum; server menyimpan kode yang di-hash dan status eksplisit. Pengguna masuk di ponsel, meninjau klien, scope, dan informasi perangkat, lalu menyetujuinya. Endpoint token hanya menerima device code: lanjutkan pada authorization_pending, tambahkan setidaknya 5 detik pada slow_down, dan hentikan pada kedaluwarsa, penolakan, atau ketidakvalidan permanen. Konsumsi kode secara atomik sehingga polling serentak tidak dapat menerbitkan dua set token. Perlakukan perangkat sebagai public client, minimalkan scope, putar refresh token, batasi tebakan, dan minta pengguna untuk membandingkan kode di kedua layar. Metrik dan pengujian mencakup pengikatan alur, backoff, pemulihan, dan batas phishing.
Kesalahan umum
- Memperlakukan device code sebagai kode yang dimasukkan manusia dan mengekspos kredensial bernilai tinggi di UI atau log.
- Mengabaikan
slow_downdan melakukan polling ke endpoint token pada tingkat tinggi yang tetap. - Mencoba ulang setiap error, termasuk kedaluwarsa dan penolakan, tanpa batas.
- Menganggap bahwa device secret statis menjadikan public client sebagai confidential client.
- Mengirim access token langsung melalui URL peramban atau skrip halaman setelah persetujuan.
- Gagal mengonsumsi device code secara atomik dan menerbitkan beberapa refresh token.
- Menguji endpoint polling secara terpisah tanpa membuktikan bahwa perangkat yang disetujui cocok dengan sesi token.
Pertanyaan lanjutan
Bagaimana Anda memilih panjang dan masa berlaku user code?
Seimbangkan kemudahan memasukkan, biaya tebakan online, dan waktu penyelesaian. Hindari karakter ambigu, batasi percobaan gagal dan tingkat agregat, serta buat masa berlaku cukup panjang agar pengguna dapat mengambil ponsel, masuk, dan mengonfirmasi perangkat tanpa menciptakan jendela phishing tanpa batas. Kalibrasikan angka dengan model ancaman dan waktu penyelesaian yang diamati.
Bagaimana Anda mencegah klien berbahaya memenuhi semua sesi?
Batasi laju pembuatan berdasarkan pendaftaran klien, IP, sidik jari perangkat, dan akun; batasi sesi yang belum selesai per prinsipal dan bersihkan sesi yang kedaluwarsa secara asinkron. Validasi klien dan scope sebelum membuat sesi. Jangan memindahkan beban pembersihan sampah device code ke endpoint token.
Bagaimana perangkat offline pulih setelah persetujuan?
Pertahankan sesi hingga kedaluwarsa agar perangkat dapat melakukan polling dengan kode yang sama setelah tersambung kembali. Kembalikan set token atau status terminal. Jadikan penanganan penebusan bersifat idempoten sehingga respons yang hilang tidak menyebabkan konsumsi kedua. Setelah kedaluwarsa, mulai ulang dengan kode baru dan beri tahu pengguna.
Apa saja risiko dari verification_uri_complete?
Menempatkan user code dalam tautan mengurangi pengetikan tetapi meningkatkan kebocoran tautan dan risiko phishing jarak jauh. Tetap tampilkan kode pendek dan minta pengguna untuk membandingkannya dengan layar perangkat. Jangan mengekspos tautan lengkap ke analitik, header Referer, riwayat, atau pengalihan pihak ketiga. Tawarkan ini hanya jika kemampuan perangkat dan model ancaman memungkinkannya.
Mengapa tidak mentransfer access token dari ponsel ke perangkat?
Transfer token lintas perangkat memperluas paparan melalui peramban, kode QR, clipboard, dan halaman perantara, serta sulit membuktikan bahwa penerima adalah perangkat yang benar. Device Flow memungkinkan perangkat menebus kodenya sendiri melalui TLS; halaman pengguna hanya mengubah status server. Tambahkan saluran jarak dekat (near-field) yang diautentikasi secara terpisah jika produk membutuhkannya.
Bagaimana Anda memverifikasi bahwa polling melakukan backoff dengan benar?
Catat jumlah polling tingkat sesi, distribusi interval, interval aktual setelah slow_down, latensi terminal, dan kegagalan yang diagregasikan per klien. Masukkan polling berulang dalam pengujian terkontrol dan verifikasi bahwa slow_down meningkatkan interval klien setidaknya 5 detik tanpa menyebabkan lonjakan tersinkronisasi. Isolasi klien yang melakukan penyalahgunaan daripada melonggarkan interval global.