REST API security Disimpan token vs JWT vs OAuth

104

Saya masih berusaha menemukan solusi keamanan terbaik untuk melindungi REST API, karena jumlah aplikasi seluler dan API meningkat setiap hari.

Saya telah mencoba berbagai cara otentikasi, tetapi masih memiliki beberapa kesalahpahaman, jadi saya perlu saran dari seseorang yang lebih berpengalaman.

Biarkan saya katakan, bagaimana saya memahami semua hal ini. Jika saya mengerti sesuatu yang salah, tolong beri tahu saya.

Sejauh REST API tidak memiliki kewarganegaraan dan juga WEB pada umumnya, kami perlu mengirim beberapa data auth dalam setiap permintaan (cookie, token ....). Saya tahu tiga mekanisme yang banyak digunakan untuk mengotentikasi pengguna

  1. Token dengan HTTPS. Saya telah menggunakan pendekatan ini berkali-kali cukup baik dengan HTTPS. Jika pengguna memberikan kata sandi dan login yang benar, ia akan menerima token sebagai respons, dan akan menggunakannya untuk permintaan lebih lanjut. Token dihasilkan oleh server dan disimpan, misalnya dalam tabel terpisah atau sama di mana info pengguna disimpan. Jadi untuk setiap server permintaan memeriksa apakah pengguna memiliki token dan itu sama seperti dalam database. Semuanya sangat mudah.

  2. Token JWT. Token ini bersifat deskriptif sendiri, berisi semua informasi yang diperlukan tentang token itu sendiri, pengguna tidak dapat mengubah misalnya tanggal kedaluwarsa atau klaim lain, karena token ini dihasilkan (ditandatangani) oleh server dengan kata kunci rahasia. Ini juga jelas. Tapi satu masalah besar, secara pribadi bagi saya, cara membatalkan token.

  3. OAuth 2. Saya tidak mengerti mengapa pendekatan ini harus digunakan ketika komunikasi dibuat langsung antara server dan klien. Sejauh yang saya mengerti, server OAuth digunakan untuk menerbitkan token dengan lingkup terbatas untuk memungkinkan aplikasi lain mengakses informasi pengguna tanpa menyimpan kata sandi dan login. Ini adalah solusi yang bagus untuk jejaring sosial, ketika pengguna ingin mendaftar di beberapa halaman, server dapat meminta izin untuk mendapatkan info pengguna, misalnya dari twitter atau facebook, dan mengisi bidang pendaftaran dengan data pengguna dan sebagainya.

Pertimbangkan klien seluler untuk toko online.

Pertanyaan pertama yang harus saya pilih JWT daripada jenis pertama token? Sejauh saya memerlukan pengguna login / logout pada klien seluler, saya perlu menyimpan token di suatu tempat atau dalam kasus JWT, token harus dibatalkan pada saat logout. Pendekatan yang berbeda digunakan untuk membatalkan token salah satunya adalah membuat daftar token yang tidak valid (black list). Hmm. Tabel / file akan memiliki ukuran yang jauh lebih besar daripada jika token disimpan dalam tabel dan dikaitkan dengan pengguna, dan baru saja dihapus saat logout.

Jadi apa manfaat token JWT?

Pertanyaan kedua tentang OAuth, haruskah saya menggunakannya jika ada komunikasi langsung dengan server saya? Apa tujuan dari satu lapisan lagi antara klien dan server hanya untuk mengeluarkan token, tetapi komunikasi tidak akan dengan server asli tetapi dengan server utama. Seperti yang saya pahami, server OAuth hanya bertanggung jawab untuk memberikan izin aplikasi pihak ketiga (token) untuk mengakses informasi pribadi pengguna. Tetapi aplikasi klien seluler saya bukan pihak ketiga.

CROSP
sumber
Terima kasih, saya ingin tahu ini baru-baru ini. Saya pergi dengan manajemen sesi (Beaker), dan menghapus token sesi setelah satu jam. Oauth sepertinya tidak pas.
JasTonAChair

Jawaban:

86

Pertimbangkan kasus pertama. Setiap klien mendapatkan ID acak yang berlangsung selama sesi - yang bisa beberapa hari jika Anda suka. Kemudian Anda menyimpan informasi yang relevan dengan sesi itu di suatu tempat di sisi server. Bisa dalam file atau database. Misalkan Anda meneruskan ID melalui cookie tetapi Anda bisa menggunakan URL atau header HTTP.

ID / Cookie Sesi

Pro:

  • Kode mudah untuk klien dan server.
  • Mudah untuk menghancurkan sesi ketika seseorang keluar.

Cons:

  • Sisi server secara berkala perlu menghapus sesi yang kadaluarsa di mana klien tidak keluar.
  • Setiap permintaan HTTP membutuhkan pencarian ke penyimpanan data.
  • Persyaratan penyimpanan bertambah karena semakin banyak pengguna yang memiliki sesi aktif.
  • Jika ada beberapa server HTTP front end, data sesi yang disimpan harus dapat diakses oleh mereka semua. Ini bisa jadi sedikit lebih banyak pekerjaan daripada menyimpannya di satu server. Masalah yang lebih besar adalah penyimpanan data menjadi titik kegagalan tunggal dan dapat menjadi hambatan.

Token Web JSON (JWT)

Dalam kasus kedua, data disimpan dalam JWT yang diedarkan alih-alih di server.

Pro:

  • Masalah penyimpanan sisi server hilang.
  • Kode sisi klien mudah.

Cons:

  • Ukuran JWT bisa lebih besar dari ID sesi. Ini dapat memengaruhi kinerja jaringan karena disertakan dengan setiap permintaan HTTP.
  • Data yang disimpan di JWT dapat dibaca oleh klien. Ini mungkin masalah.
  • Sisi server memerlukan kode untuk menghasilkan, memvalidasi, dan membaca JWT. Itu tidak sulit tetapi ada sedikit kurva belajar dan keamanan tergantung padanya.

    Siapa pun yang mendapatkan salinan kunci tanda tangan dapat membuat JWT. Anda mungkin tidak tahu kapan ini terjadi.

    Ada bug di beberapa perpustakaan yang menerima JWT yang ditandatangani dengan algoritme "tidak" sehingga siapa pun dapat membuat JWT yang dipercayai oleh server.

  • Untuk mencabut JWT sebelum kedaluwarsa, Anda perlu menggunakan daftar pencabutan. Ini membuat Anda kembali ke masalah penyimpanan sisi server yang Anda coba hindari.

OAuth

Seringkali OAuth digunakan untuk otentikasi (yaitu identitas) tetapi dapat digunakan untuk berbagi data lain seperti daftar konten yang telah dibeli pengguna dan berhak untuk diunduh. Itu juga dapat digunakan untuk memberikan akses untuk menulis ke data yang disimpan oleh pihak ketiga. Anda mungkin menggunakan OAuth untuk mengautentikasi pengguna dan kemudian menggunakan penyimpanan sisi server atau JWT untuk data sesi.

Pro:

  • Tidak ada kode bagi pengguna untuk mendaftar atau mengatur ulang kata sandi mereka.
  • Tidak ada kode untuk mengirim email dengan tautan validasi dan kemudian memvalidasi alamat.
  • Pengguna tidak perlu mempelajari / menuliskan nama pengguna dan kata sandi lain.

Cons:

  • Anda bergantung pada pihak ketiga agar pengguna Anda dapat menggunakan layanan Anda. Jika layanan mereka turun atau mereka menghentikannya maka Anda perlu memikirkan hal lain. Misalnya: bagaimana Anda memigrasikan data akun pengguna jika identitas mereka berubah dari "[email protected]" menjadi "[email protected]"?
  • Biasanya Anda harus menulis kode untuk setiap penyedia. misal Google, Facebook, Twitter.
  • Anda atau pengguna Anda mungkin memiliki masalah privasi. Penyedia tahu pengguna mana yang menggunakan layanan Anda.
  • Anda mempercayai penyedia. Dimungkinkan bagi penyedia untuk menerbitkan token yang berlaku untuk satu pengguna kepada orang lain. Ini bisa untuk tujuan yang sah atau tidak.

Lain-lain

  • ID sesi dan JWT dapat disalin dan digunakan oleh banyak pengguna. Anda dapat menyimpan alamat IP klien dalam JWT dan memvalidasinya tetapi itu mencegah klien dari roaming dari mengatakan Wi-Fi ke seluler.
Chad Clark
sumber
Untuk menambah jawaban Anda, oAuth mungkin tidak berguna ketika pengguna ingin mendaftar menggunakan akun perusahaan mereka yang biasanya tidak dikaitkan atau ditautkan dengan situs jejaring sosial atau google.
Aftab Naveed
5
Saya tidak tahu mengapa ini adalah jawaban yang diterima? itu tidak menjawab pertanyaan yang sebenarnya, hanya reformasi pertanyaan dengan cara lain
amd
1
Anda berkata: "Data yang disimpan dalam JWT dapat dibaca oleh klien. Ini mungkin masalah .. Mengapa tidak menggunakan JWE jika itu masalah?
Perak
Jawaban ini membingungkan apel & jeruk. Anda tidak harus membandingkan ini dengan OAuth 2.0 (spesifikasi "otorisasi"). Yang perlu diketahui OP adalah: "Alur Kata Sandi Pemilik Sumber Daya" - yang merupakan otentikasi sebagai hibah.
Onur Yıldırım
5

Tanyakan kepada diri sendiri mengapa Anda perlu membatalkan token asli.

Seorang pengguna masuk, token dihasilkan dan keluar dari aplikasi berjalan.

Pengguna menekan logout, token baru dihasilkan dan menggantikan token asli. Sekali lagi, semuanya baik-baik saja.

Anda tampaknya khawatir tentang kasus di mana kedua token berkeliaran. Bagaimana jika pengguna keluar dan entah bagaimana membuat permintaan menggunakan token yang masuk. Seberapa realistis skenario ini? Apakah ini hanya masalah selama logout atau apakah ada banyak skenario di mana beberapa token bisa menjadi masalah?

Saya sendiri tidak berpikir itu layak dikhawatirkan. Jika seseorang mencegat dan mendekode data https terenkripsi Anda maka Anda memiliki masalah yang jauh lebih besar.

Anda dapat memberi diri Anda beberapa perlindungan tambahan dengan meletakkan waktu kedaluwarsa pada token asli. Jadi jika akhirnya dicuri atau sesuatu, maka itu hanya baik untuk jangka waktu yang singkat.

Kalau tidak, saya pikir Anda perlu memiliki informasi negara di server. Jangan mencantumkan token daftar hitam, tetapi sebagai gantinya membolehkan tanda tangan token saat ini.

Cerad
sumber
2
Jika Anda berasumsi bahwa beberapa klien Anda berbahaya, maka mudah untuk melihat bahwa sesi akan disalin dan digunakan kembali, dan Anda perlu mengatasinya di server.
Michael Shaw
1
Gagasan buruk, ini bisa digunakan nanti oleh peretas, atau hanya dengan paksa ...
CROSP
2
Bayangkan seorang pengguna ingin keluar dari semua perangkat lain, menggunakan JWT tidak mungkin.
amd
@ md tidak mungkin? Bagaimana jika saya menambahkan nonce = (acak) dan jika pengguna keluar, ganti nonce. Tampak sederhana dan efektif.
Simon B.
3

Anda bisa menangani masalah JWT yang Anda sebutkan dengan menyimpan nilai garam bersama dengan pengguna dan menggunakan garam sebagai bagian dari token untuk pengguna. Kemudian ketika Anda perlu membatalkan token, cukup ganti garamnya.

Saya tahu ini sudah beberapa tahun tetapi saya sebenarnya akan melakukan ini secara berbeda sekarang. Saya pikir saya akan memastikan bahwa token akses memiliki masa hidup yang relatif singkat, katakan satu jam. Saya juga pasti akan menggunakan token penyegaran yang stateful di server dan kemudian ketika saya ingin mengakhiri sesi seseorang, saya akan mencabut token penyegaran dengan menghapusnya dari server. Kemudian setelah satu jam, pengguna akan keluar dan harus masuk lagi untuk mendapatkan kembali akses.

RibaldEddie
sumber
4
Tetapi sekali lagi ini menjadi keadaan penuh dalam kasus ini, jadi apa alasan untuk membuat garam atau menggunakan pendekatan lain, Anda dapat menyimpan token sederhana dalam tabel dan menghapus kapan itu harus dibatalkan
CROSP
2
Anda juga dapat membatalkan berdasarkan waktu.
RibaldEddie
Apa perbedaan antara waktu kedaluwarsa dalam kasus ini? Bagaimana saya bisa membatalkan token berdasarkan waktu ketika pengguna ingin keluar dari klien seluler? Tampaknya tidak ada cara API untuk menjadi stateless dalam kasus ini. Apa solusi yang paling cocok dan aman daripada?
CROSP
2
Yang paling cocok untuk keluar dari satu perangkat adalah untuk memastikan bahwa Anda menggunakan clientId selain garam. Saya sarankan Anda melihat spek token pembawa Oauth-jwt untuk wawasan.
RibaldEddie
Terima kasih atas jawabannya, tetapi saya tidak mengerti mengapa saya harus menggunakan OAuth dalam kasus ini sama sekali.
CROSP