Jika aplikasi REST seharusnya tanpa kewarganegaraan, bagaimana Anda mengelola sesi?

536

Saya perlu klarifikasi. Saya telah membaca tentang REST, dan membangun aplikasi yang tenang. Menurut wikipedia, REST sendiri didefinisikan sebagai Transfer Negara Representasi . Karena itu saya tidak mengerti semua gobbledeygook stateless ini bahwa semua orang terus memuntahkan.

Dari wikipedia:

Pada waktu tertentu, klien dapat dalam transisi antara status aplikasi atau "diam". Klien dalam keadaan diam dapat berinteraksi dengan penggunanya, tetapi tidak menciptakan beban dan tidak mengkonsumsi penyimpanan per-klien di set server atau di jaringan.

Apakah mereka hanya mengatakan tidak menggunakan data tingkat sesi / aplikasi ???

Saya mendapatkan bahwa salah satu tujuan REST adalah membuat akses URI konsisten dan tersedia, misalnya, alih-alih menyembunyikan permintaan paging di dalam posting, menjadikan nomor halaman dari permintaan bagian dari GET URI. Masuk akal bagi saya. Tetapi sepertinya itu hanya berlebihan mengatakan bahwa tidak ada data klien (data sesi) yang harus disimpan di sisi server.

Bagaimana jika saya memiliki antrian pesan, dan pengguna saya ingin membaca pesan, tetapi ketika dia membacanya, ingin memblokir pesan pengirim tertentu yang datang selama sesi berlangsung? Tidakkah masuk akal untuk menyimpan ini di tempat di sisi server, dan apakah server hanya mengirim pesan (atau ID pesan) yang tidak diblokir oleh pengguna?

Apakah saya harus mengirim seluruh daftar pengirim pesan untuk diblokir setiap kali saya meminta daftar pesan baru? Daftar pesan yang berkaitan dengan saya tidak akan / seharusnya tidak menjadi sumber daya yang tersedia untuk umum di tempat pertama ..

Sekali lagi, hanya mencoba memahami ini. Seseorang tolong jelaskan.


Memperbarui:

Saya telah menemukan sebuah pertanyaan stack overflow yang memiliki jawaban yang tidak cukup mendapatkan saya sepanjang perjalanan ke sana: Bagaimana mengelola negara dalam SISA yang mengatakan bahwa negara klien yang penting harus semua ditransfer pada setiap permintaan .... Ugg .. sepertinya banyak overhead ... Apakah ini benar ??

Zak
sumber
2
@ S.Lott: Saya tidak berpikir itu sengaja menyesatkan. Saya pikir ini adalah kesalahpahaman karena terminologi yang membingungkan.
HANYA SAYA PENDAPAT benar
2
@ HANYA SAYA OPINI yang benar: Tebakan yang menarik. Saya tidak bisa mempercayai hal seperti itu, saya sendiri, karena jelas dari "stateless" berarti protokol REST itu sendiri stateless; yang tidak mengatakan apa-apa tentang status aplikasi yang mendasarinya dan memutakhirkannya dengan permintaan PUT, POST dan DELETE.
S.Lott
@ S.Lott: Protokol HTTP itu sendiri tidak memiliki kewarganegaraan. Dari apa yang telah kita bahas di bawah ini, REST adalah sudut pandang tentang bagaimana membangun aplikasi Anda sementara tidak memiliki server web menangani keadaan sesi (sebagai lawan dari keadaan lain dalam hal-hal seperti DB). Saya bahkan tidak berpikir REST adalah protokol, tetapi lebih pada pandangan tentang cara menggunakan protokol HTTP. Saya pikir kalian menjelaskan bahwa ini adalah tentang bagaimana membangun aplikasi Anda untuk skala dengan meminta sisi klien menyimpan semua data sesi khusus klien, dan membuat akses URI semaksimal mungkin, kecuali di mana seharusnya tidak. Mungkin tidak ... :(
Zak
1
"Mungkin tidak .." Apa artinya itu? Anda punya pertanyaan baru? Silakan mencari SO untuk itu. Jika tidak ada di sini, maka tanyakan.
S.Lott
Adakah yang membaca REST in Practice dari Webber, Parastatidis, dan Robinson (atau melihat contoh restbucks mereka)? Jawaban di bawah ini masuk akal, tetapi tentu saja pesanan kopi dalam contoh restbucks menyatakan tentang klien? Jumlah pesanan berskala dengan jumlah klien. Di mana garis antara status klien dan sumber daya?
Rikki

Jawaban:

340

Statelessness berarti bahwa setiap permintaan HTTP terjadi dalam isolasi lengkap. Ketika klien membuat permintaan HTTP, itu mencakup semua informasi yang diperlukan untuk server untuk memenuhi permintaan itu. Server tidak pernah bergantung pada informasi dari permintaan sebelumnya. Jika informasi itu penting, klien harus mengirimnya lagi dalam permintaan berikutnya. Statelessness juga menghadirkan fitur-fitur baru. Lebih mudah untuk mendistribusikan aplikasi tanpa negara di server dengan beban yang seimbang. Aplikasi stateless juga mudah di-cache.

Sebenarnya ada dua jenis negara. Status Aplikasi yang hidup pada klien dan Status Sumber Daya yang hidup di server.

Layanan web hanya perlu peduli dengan status aplikasi Anda saat Anda benar-benar mengajukan permintaan. Sisa waktu, bahkan tidak tahu Anda ada. Ini berarti bahwa setiap kali klien mengajukan permintaan, itu harus mencakup semua status aplikasi yang diperlukan server untuk memprosesnya.

Status sumber daya adalah sama untuk setiap klien, dan tempat yang tepat adalah di server. Saat Anda mengunggah gambar ke server, Anda membuat sumber daya baru: gambar baru memiliki URI sendiri dan dapat menjadi target permintaan di masa mendatang. Anda dapat mengambil, mengubah, dan menghapus sumber ini melalui HTTP.

Semoga ini membantu membedakan apa yang dimaksud dengan kewarganegaraan dan berbagai negara.

Srikar Doddi
sumber
4
Apakah ini berarti bahwa setiap kali permintaan dikirim, klien harus mengirim pengguna / kata sandi untuk mengotentikasi? Karena saya kira menyimpan sesi, bahkan jika itu pada no-sql db bersama di antara semua server, bukan stateless, atau bukan?
Carlos Navarro Astiasarán
1
@ CarlosNavarroAstiasarán ada berbagai teknik untuk menangani otentikasi stateless. Google JWT misalnya.
geoidesic
1
@geoidesic: "Karena token web JSON adalah stateless, tidak ada cara untuk membatalkannya tanpa menyimpan status server, sehingga mengalahkan keuntungan token stateless." WIkipedia
ulatekh
@ulatekh Itu adalah penggambaran yang keliru tentang apa yang dapat Anda lakukan dengan token. Cukup mudah untuk menyimpan ID yang disetujui bersama dengan token dan hanya menerima token yang memiliki ID yang disetujui sebagai klaim. Stateless bukan berarti Anda tidak bisa melakukan sesuatu dalam basis data. Pada dasarnya Anda menyimpan ID dalam database yang harus cocok dengan ID yang sama di token. Untuk mencabut token Anda menghapus ID dari database. Tidak ada status yang diingat dalam layanan itu sendiri. Atau bahkan lebih baik Anda menyimpan kunci tanda dengan pengguna di database dan mencabut kunci.
Andrew T Finnell
@AndrewTFinnell: Jika Anda harus menyimpan ID yang disetujui di server, maka itu harus disimpan di semua server potensial yang dapat memproses login REST, yang dapat melibatkan banyak keadaan server di arsitektur web-server paralel yang masif.
ulatekh
491

Penjelasan mendasar adalah:

Tidak ada status sesi klien di server.

Dengan stateless itu berarti server tidak menyimpan keadaan apa pun tentang sesi klien di sisi server.

The sesi klien disimpan pada klien. Server tanpa kewarganegaraan berarti bahwa setiap server dapat melayani setiap klien kapan saja, tidak ada sesi afinitas atau sesi lengket . Informasi sesi yang relevan disimpan pada klien dan diteruskan ke server sesuai kebutuhan.

Itu tidak menghalangi layanan lain yang dibicarakan oleh server web untuk mempertahankan status tentang objek bisnis seperti keranjang belanja, hanya saja tidak tentang status aplikasi / sesi klien saat ini.

The klien negara aplikasi tidak boleh disimpan di server, namun diedarkan dari client ke setiap tempat yang memerlukannya.

Dari situlah ST in REST berasal, State Transfer . Anda mentransfer keadaan sekitar alih-alih meminta server menyimpannya. Ini adalah satu-satunya cara untuk skala ke jutaan pengguna bersamaan. Jika tidak ada alasan lain selain karena jutaan sesi adalah jutaan sesi.

Beban manajemen sesi diamortisasi di semua klien, klien menyimpan status sesi mereka dan server dapat melayani banyak pesanan besar atau lebih banyak klien secara stateless.

Bahkan untuk layanan yang menurut Anda hanya perlu dalam 10 dari ribuan pengguna secara bersamaan, Anda tetap harus membuat layanan Anda tanpa kewarganegaraan. Puluhan ribu masih puluhan ribu dan akan ada biaya waktu dan ruang yang terkait dengannya.

Stateless adalah bagaimana protokol HTTP dan web pada umumnya dirancang untuk beroperasi dan merupakan implementasi yang lebih sederhana secara keseluruhan dan Anda memiliki jalur kode tunggal alih-alih sekelompok logika sisi server untuk mempertahankan banyak status sesi.

Ada beberapa prinsip implementasi yang sangat mendasar:

Ini adalah prinsip yang bukan implementasi, bagaimana Anda memenuhi prinsip-prinsip ini dapat berbeda.

Singkatnya, lima prinsip utama adalah:

  1. Berikan setiap "hal" ID
  2. Tautkan hal-hal bersama
  3. Gunakan metode standar
  4. Sumber daya dengan banyak representasi
  5. Berkomunikasi tanpa kewarganegaraan

Tidak ada apapun tentang otentikasi atau otorisasi dalam disertasi REST .

Karena tidak ada yang berbeda dari mengotentikasi permintaan yang TENANG dari yang tidak. Otentikasi tidak relevan dengan diskusi RESTful.

Menjelaskan cara membuat aplikasi stateless untuk persyaratan khusus Anda, terlalu luas untuk StackOverflow.

Menerapkan Otentikasi dan Otorisasi yang berkaitan dengan REST bahkan lebih luas dan berbagai pendekatan untuk implementasi dijelaskan dengan sangat rinci di internet pada umumnya.

Komentar yang meminta bantuan / info tentang ini akan / seharusnya ditandai sebagai Tidak Lagi Dibutuhkan .


sumber
22
Itu tampak seperti pernyataan yang cukup berani bahwa itu adalah satu - satunya cara untuk skala ke jutaan pengguna. Mengapa sesi sisi server tidak bisa menjadi layanan lain?
Zak
27
@ Zak: Karena jutaan sesi adalah jutaan sesi. Intinya adalah untuk menghindari overhead dari semua manajemen sesi ini.
S.Lott
91
itu bukan keberanian itu adalah pengalaman
21
Tidak ada dalam jawaban saya yang menyiratkan solusi berdasarkan akses basis data pada setiap permintaan, jika menurut Anda itu solusi, itu adalah bagian Anda yang gagal memahami otentikasi dan otorisasi pada skala itu. Otentikasi dapat tersirat di negara bagian, apakah Anda pikir facebook melakukan "akses basis data" pada setiap permintaan API REST-nya? Atau Google dalam hal ini? petunjuk: tidak
6
Jadi, jika saya menyimpan status pengguna dalam cache terdistribusi mengatakan memcache, dan semua server web saya sekarang tidak perlu menyimpan status apa pun selain pergi dan mendapatkan status dari memcache, dapatkah saya menganggap aplikasi ini tanpa kewarganegaraan?
Jaskey
76

Apakah mereka hanya mengatakan tidak menggunakan data tingkat sesi / aplikasi ???

Tidak. Mereka tidak mengatakan itu dengan cara sepele.

Mereka mengatakan tidak mendefinisikan "sesi". Jangan login. Jangan keluar. Berikan kredensial dengan permintaan tersebut. Setiap permintaan berdiri sendiri.

Anda masih memiliki penyimpanan data. Anda masih memiliki otentikasi dan otorisasi. Anda hanya tidak membuang waktu untuk membuat sesi dan mempertahankan status sesi.

Intinya adalah bahwa setiap permintaan (a) berdiri sendiri dan (b) dapat secara sepele ditanami ke server paralel pertanian raksasa tanpa pekerjaan yang sebenarnya. Apache atau Squid dapat melewati permintaan RESTful sekitar secara membabi buta dan berhasil.

Bagaimana jika saya memiliki antrian pesan, dan pengguna saya ingin membaca pesan, tetapi ketika dia membacanya, ingin memblokir pesan pengirim tertentu yang datang selama sesi berlangsung?

Jika pengguna menginginkan filter, maka cukup sediakan filter pada setiap permintaan.

Tidakkah masuk akal untuk ... memiliki server hanya mengirim pesan (atau ID pesan) yang tidak diblokir oleh pengguna?

Iya. Berikan filter dalam permintaan URI TENANG.

Apakah saya harus mengirim seluruh daftar pengirim pesan untuk diblokir setiap kali saya meminta daftar pesan baru?

Iya. Seberapa besar "daftar pengirim pesan yang akan diblokir" ini? Daftar singkat PK?

Permintaan GET bisa sangat besar. Jika perlu, Anda dapat mencoba permintaan POST meskipun itu terdengar seperti semacam permintaan.

S.Lott
sumber
28
"Jangan masuk. Jangan keluar. Berikan kredensial dengan permintaan." Saya selalu melihat respons seperti ini dalam pertanyaan tentang cara tetap tanpa kewarganegaraan dalam API REST tanpa rincian tentang di mana / bagaimana seseorang harus menyimpan kredensial tersebut pada klien. Tentunya kita tidak boleh menyimpan nama pengguna dan kata sandi di penyimpanan lokal!
BeniRose
2
@BeniRose tidak bisakah kita menyimpan token di penyimpanan lokal dan menggunakan token itu dalam permintaan yang akan mengidentifikasi pengguna secara unik?
Nikhil Sahu
1
Penyimpanan lokal memiliki banyak masalah keamanan dari apa yang saya mengerti. Tetapi juga ada banyak masalah lain dengan sesi sisi klien, seperti token yang tidak valid, keluar dari pengguna, dll.
BeniRose
3
Anda menggunakan JWT yang memiliki tanda tangan, verifikasi tanda tangan cepat sehingga Anda dapat memeriksa validitas negara itu.
Archimedes Trajano
36

Anda benar, mendukung interaksi yang benar-benar tanpa kewarganegaraan dengan server tidak membebani klien. Namun, jika Anda mempertimbangkan untuk menskala aplikasi, kekuatan perhitungan klien berbanding lurus dengan jumlah klien. Oleh karena itu penskalaan ke jumlah klien yang tinggi jauh lebih layak.

Segera setelah Anda menaruh sedikit tanggung jawab pada server untuk mengelola beberapa informasi yang berkaitan dengan interaksi klien tertentu, beban itu dapat dengan cepat bertambah untuk mengkonsumsi server.

Ini adalah trade off.

Darrel Miller
sumber
32

Pandangan historis manajemen negara aplikasi pengguna

Sesi dalam pengertian tradisional menjaga status pengguna dalam aplikasi di dalam server. Ini mungkin halaman saat ini dalam aliran atau apa yang telah dimasukkan sebelumnya tetapi belum bertahan ke database utama.

Alasan untuk kebutuhan ini adalah kurangnya standar di sisi klien untuk secara efektif mempertahankan negara tanpa membuat aplikasi atau plug-in khusus klien (khusus browser).

HTML5 dan XML Header Request telah lama menstandarkan gagasan untuk menyimpan data yang kompleks termasuk status aplikasi dengan cara standar di sisi klien (yaitu browser) tanpa harus bolak-balik di antara server.

Penggunaan umum layanan REST

Layanan REST umumnya disebut ketika ada transaksi yang perlu dilakukan atau jika perlu mengambil data.

Layanan REST dimaksudkan untuk dipanggil oleh aplikasi sisi klien dan bukan pengguna akhir secara langsung.

Otentikasi

Untuk setiap permintaan ke server, bagian dari permintaan harus berisi token otorisasi. Cara penerapannya adalah khusus aplikasi, tetapi secara umum bisa berupa BASICatau CERTIFICATEbentuk otentikasi.

Otentikasi berbasis formulir tidak digunakan oleh layanan REST. Namun, sebagaimana disebutkan di atas layanan REST tidak dimaksudkan untuk dipanggil oleh pengguna, tetapi oleh aplikasi. Aplikasi perlu mengelola mendapatkan token otentikasi. Dalam kasus saya, saya menggunakan cookie dengan JASPIC dengan OAuth 2.0 untuk terhubung ke Google untuk otentikasi dan Otentikasi HTTP sederhana untuk pengujian otomatis. Saya juga menggunakan otentikasi HTTP Header melalui JASPIC untuk pengujian lokal juga (meskipun pendekatan yang sama dapat dilakukan di SiteMinder)

Sebagai contoh, otentikasi dikelola pada sisi klien (meskipun SiteMinder atau Google akan menyimpan sesi otentikasi pada akhirnya), tidak ada yang dapat dilakukan tentang keadaan itu, tetapi itu bukan bagian dari aplikasi layanan REST.

Permintaan pengambilan

Permintaan pengambilan di REST adalah GEToperasi di mana sumber daya tertentu diminta dan dapat disimpan dalam cache. Tidak perlu untuk sesi server karena permintaan memiliki semua yang diperlukan untuk mengambil data: otentikasi dan URI.

Skrip transaksi

Seperti disebutkan di atas, aplikasi sisi klien itu sendiri memanggil layanan REST bersama dengan otentikasi yang dikelola di sisi klien juga.

Apa artinya ini untuk layanan REST [jika dilakukan dengan benar] adalah untuk mengambil satu permintaan ke server REST akan berisi semua yang diperlukan untuk operasi pengguna tunggal yang melakukan semua yang diperlukan dalam satu transaksi tunggal, Skrip Transaksi adalah apa pola disebut.

Ini biasanya dilakukan melalui POSTpermintaan, tetapi yang lain PUTjuga bisa digunakan.

Banyak contoh REST yang dibuat-buat (saya sendiri melakukan ini) mencoba mengikuti sebanyak apa yang telah didefinisikan dalam protokol HTTP, setelah melalui itu saya memutuskan untuk lebih pragmatis dan menyerahkannya pada GET dan POST saja . The POSTMetode bahkan tidak harus menerapkan pola POST-REDIRECT-GET.

Namun demikian, seperti yang telah saya catat di atas, aplikasi sisi klien akan menjadi orang yang memanggil layanan dan hanya akan memanggil POSTpermintaan dengan semua data saat diperlukan (tidak setiap waktu). Ini mencegah permintaan konstan ke server.

Jajak pendapat

Meskipun REST dapat digunakan untuk polling juga, saya tidak akan merekomendasikan hal ini kecuali Anda harus menggunakannya karena kompatibilitas browser. Untuk itu saya akan menggunakan WebSockets yang telah saya rancang kontrak API juga. Alternatif lain untuk browser lama adalah CometD.

Archimedes Trajano
sumber
27

REST sangat abstrak. Membantu memiliki beberapa contoh dunia nyata yang baik, sederhana, dan nyata.

Ambil contoh semua aplikasi media sosial utama - Tumblr, Instagram, Facebook, dan Twitter. Mereka semua memiliki tampilan gulir selamanya di mana semakin jauh Anda menggulir ke bawah, semakin banyak konten yang Anda lihat, semakin jauh ke masa lalu. Namun, kita semua mengalami saat di mana Anda kehilangan tempat Anda digulir ke, dan aplikasi mengembalikan Anda ke atas. Seperti jika Anda keluar dari aplikasi, maka ketika Anda membukanya kembali, Anda kembali di atas lagi.

Alasannya, karena server tidak menyimpan status sesi Anda. Sayangnya, posisi gulir Anda baru saja disimpan dalam RAM di klien.

Untungnya Anda tidak harus masuk kembali saat tersambung kembali, tetapi itu hanya karena sisi klien Anda juga menyimpan sertifikat masuk yang belum kedaluwarsa. Hapus dan instal ulang aplikasi, dan Anda harus masuk kembali, karena server tidak mengaitkan alamat IP Anda dengan sesi Anda.

Anda tidak memiliki sesi login di server, karena mereka mematuhi REST.


Sekarang contoh di atas tidak melibatkan browser web sama sekali, tetapi di bagian belakang, aplikasi berkomunikasi melalui HTTPS dengan server host mereka. Maksud saya adalah bahwa REST tidak harus melibatkan cookie dan browser, dll. Ada berbagai cara untuk menyimpan keadaan sesi sisi klien.

Tetapi mari kita bicara tentang peramban web sebentar, karena itu memunculkan keuntungan besar lain dari REST yang tidak dibicarakan oleh siapa pun di sini.

Jika server mencoba menyimpan status sesi, bagaimana seharusnya mengidentifikasi setiap klien?

Itu tidak dapat menggunakan alamat IP mereka, karena banyak orang bisa menggunakan alamat yang sama pada router bersama. Jadi bagaimana?

Itu tidak dapat menggunakan alamat MAC karena berbagai alasan, paling tidak karena Anda dapat login ke beberapa akun Facebook yang berbeda secara bersamaan di browser yang berbeda plus aplikasi. Satu peramban dapat dengan mudah berpura-pura menjadi peramban lain, dan alamat MAC juga mudah dipalsukan.

Jika server harus menyimpan keadaan sisi klien untuk mengidentifikasi Anda, server harus menyimpannya dalam RAM lebih lama dari waktu yang diperlukan untuk memproses permintaan Anda, atau harus menyimpan data tersebut di cache. Server memiliki jumlah RAM dan cache yang terbatas, belum lagi kecepatan prosesor. Status sisi server menambah ketiganya secara eksponensial. Ditambah lagi jika server akan menyimpan status apa pun tentang sesi Anda, maka server harus menyimpannya secara terpisah untuk setiap browser dan aplikasi yang saat ini Anda masuki, dan juga untuk setiap perangkat berbeda yang Anda gunakan.


Jadi ... Saya harap Anda mengerti mengapa REST sangat penting untuk skalabilitas. Saya harap Anda dapat mulai melihat mengapa status sesi sisi server untuk skalabilitas server apa yang dilas pada landasan untuk akselerasi mobil.


Di mana orang menjadi bingung adalah dengan berpikir bahwa "negara" mengacu pada, seperti, informasi yang disimpan dalam database. Tidak, ini merujuk pada informasi apa pun yang perlu berada di RAM server ketika Anda menggunakannya.

CommaToast
sumber
13

Saya melihat bahwa masalah mendasar di sini adalah mencampuradukkan Sesi dengan Negara . Dan sementara REST menentukan bahwa Anda TIDAK harus menyimpan Negara di server, tidak ada yang mencegah Anda menyimpan Sesi pengguna .

Mengelola Negara di server berarti bahwa server Anda tahu persis apa yang dilakukan klien (halaman apa yang mereka lihat di bagian aplikasi yang mana). Dan ini yang tidak perlu Anda lakukan.

Saya setuju dengan orang lain yang mengatakan bahwa Anda harus menjaga penyimpanan sesi ke ukuran minimum; dan sementara itu akal sehat, sebenarnya juga tergantung pada aplikasi. Jadi, singkatnya, Anda masih dapat menyimpan sesi dengan data yang di-cache untuk menangani permintaan dengan beban lebih sedikit di server, dan mengelola otentikasi dengan menyediakan token otentikasi / akses sementara untuk digunakan klien. Setiap kali sesi / token berakhir, buat yang baru dan minta klien untuk menggunakannya.

Seseorang mungkin berpendapat bahwa klien harus menghasilkan token dengan lebih baik. Saya katakan ini bekerja dua arah, dan itu akan tergantung pada aplikasi, dan siapa yang akan bekerja dengan API.

Juga menyimpan beberapa data sesi sensitif di server harus menjadi cara yang tepat untuk dilakukan. Anda tidak dapat mempercayai klien untuk menyimpan keranjang belanja mereka yang (misalnya) berisi bidang bernama "isFreeGift". Informasi tersebut harus disimpan di server.

Tautan video yang disediakan oleh Santanu Dey dalam jawabannya sangat membantu. Tonton jika Anda belum.

Hanya catatan tambahan: Tampaknya semua jawaban yang sudah diberikan tampaknya mengabaikan fakta bahwa beberapa operasi dapat menyebabkan beban yang berat pada server. Itu relevan dalam hal konsumsi daya, konsumsi perangkat keras, dan biaya (untuk server yang disewa oleh siklus CPU). Pengembang yang baik tidak boleh malas dalam mengoptimalkan aplikasi mereka, bahkan jika operasi dapat dilakukan dengan sangat cepat pada CPU modern pada beberapa server sewaan yang mereka tidak membayar tagihan listrik dan pemeliharaan.

Meskipun pertanyaannya berumur beberapa tahun, saya harap jawaban saya tetap membantu.

Sam Sirry
sumber
4
Saya umumnya setuju dengan sentimen ini, tetapi ada kecenderungan baru-baru ini untuk mengklaim bahwa bahkan pengidentifikasi sesi tidak boleh disimpan di server. Saya belum menemukan solusi alternatifnya, JWT disebut-sebut baik, tetapi hadir dengan beberapa gotchas: cryto.net/ ~ joepie91
blog
11

Stateless berarti status layanan tidak bertahan antara permintaan dan respons selanjutnya. Setiap permintaan membawa kredensial penggunanya sendiri dan diautentikasi secara individual. Namun dalam keadaan masing-masing permintaan diketahui dari permintaan sebelumnya. Semua permintaan stateful berorientasi pada sesi yaitu setiap permintaan harus tahu dan mempertahankan perubahan yang dibuat dalam permintaan sebelumnya.

Aplikasi perbankan adalah contoh aplikasi stateful. Di mana pengguna pertama kali masuk lalu melakukan transaksi dan logout. Jika setelah pengguna logout akan mencoba melakukan transaksi, ia tidak akan dapat melakukannya.

Ya, protokol http pada dasarnya adalah protokol tanpa kewarganegaraan, tetapi untuk membuatnya stateful, kami membuat kami dari cookie HTTP. Jadi, apakah SOAP secara default. Tapi itu bisa menjadi stateful juga, tergantung pada framework yang Anda gunakan.

HTTP tidak memiliki kewarganegaraan tetapi kita masih bisa mempertahankan sesi dalam aplikasi java kita dengan menggunakan mekanisme pelacakan sesi yang berbeda.

Ya, Kami juga dapat mempertahankan sesi dalam layanan web apakah itu REST atau SOAP. Ini dapat diimplementasikan dengan menggunakan perpustakaan pihak ketiga mana pun atau Anda dapat menerapkannya sendiri.

Diambil dari http://gopaldas.org/webservices/soap/webservice-is-stateful-or-stateless-rest-soap

Ata ul Mustafa
sumber
11

Tidak ada sendok.

Jangan memikirkan kewarganegaraan seperti "mengirim semua barang Anda ke server lagi dan lagi". Tidak mungkin. Akan selalu ada status, selalu - basis data itu sendiri adalah jenis keadaan, Anda adalah pengguna terdaftar, jadi setiap rangkaian info sisi klien tidak akan valid tanpa sisi server. Secara teknis, Anda tidak pernah benar - benar tanpa kewarganegaraan.

Sepatah kata pada Login Setiap Saat Debat

Apa artinya bahkan tidak menyimpan sesi dan masuk setiap saat? Beberapa berarti "kirim kata sandi setiap kali", itu benar-benar bodoh. Ada yang bilang "nah tentu saja tidak, kirim a token sebagai gantinya" - lihat dan lihat, sesi PHP hampir melakukan hal itu. Ini mengirimkan id sesi yang merupakan semacam token dan membantu Anda mencapai barang-barang pribadi Anda tanpa mengirim ulang u / pw setiap kali. Ini juga cukup andal dan teruji dengan baik. Dan ya, nyaman, yang bisa berubah menjadi kelemahan, lihat paragraf berikutnya.

Kurangi jejak

Apa yang harus Anda lakukan , sebaliknya, dan apa yang masuk akal, adalah mengencerkan jejak webserver Anda seminimal mungkin. Bahasa seperti PHP membuatnya sangat mudah untuk hanya memasukkan segala sesuatu di penyimpanan sesi - tetapi sesi memiliki label harga. Jika Anda memiliki beberapa webservers, mereka perlu berbagi info sesi, karena mereka juga berbagi beban - salah satu dari mereka mungkin harus melayani permintaan berikutnya.

Penyimpanan bersama adalah suatu keharusan. Server perlu tahu setidaknya jika seseorang masuk atau tidak. (Dan jika Anda mengganggu database setiap kali Anda perlu memutuskan ini, Anda praktis akan hancur.) Penyimpanan bersama harus jauh lebih cepat daripada database. Ini membawa godaan: oke, saya memiliki penyimpanan yang sangat cepat, mengapa tidak melakukan semuanya di sana? - dan di situlah segala sesuatunya menjadi buruk.

Jadi maksud Anda, simpan penyimpanan sesi seminimal mungkin?

Sekali lagi, ini keputusan Anda. Anda dapat menyimpan barang-barang di sana karena alasan kinerja (database hampir selalu lebih lambat dari Redis), Anda dapat menyimpan informasi secara berlebihan, menerapkan caching Anda sendiri, apa pun - perlu diingat bahwa server web akan memiliki beban yang lebih besar jika Anda menyimpan banyak sampah pada mereka. Juga, jika mereka rusak karena beban berat (dan mereka akan), Anda kehilangan informasi berharga; dengan cara berpikir REST, semua yang terjadi dalam kasus ini adalah klien mengirim permintaan yang sama (!) dan dilayani kali ini.

Bagaimana cara melakukannya saat itu?

Tidak ada solusi yang cocok untuk semua di sini. Saya akan mengatakan memilih tingkat kewarganegaraan dan pergi dengan itu. Sesi mungkin dicintai oleh beberapa orang dan dibenci oleh orang lain tetapi mereka tidak ke mana-mana. Dengan setiap permintaan, kirim sebanyak mungkin informasi yang masuk akal, sedikit lebih mungkin; tetapi jangan menafsirkan kewarganegaraan sebagai tidak memiliki sesi, atau sebagai login setiap waktu.Entah bagaimana server harus tahu itu Anda ; Id sesi PHP adalah salah satu cara yang baik, token yang dihasilkan secara manual adalah cara lain.

Pikirkan dan putuskan, jangan biarkan tren desain berpikir untuk Anda.

dkellner
sumber
1
"Pikirkan dan putuskan, jangan biarkan tren desain berpikir untukmu." sayangnya itu menjadi sangat umum saat ini hanya mengikuti tren dengan bodoh. Terkadang membaca SO Anda akan mendapatkan semua jawaban yang sama hanya karena tren.
100r
Ya, saya sudah melihat ini di banyak topik dan ketika saya menyadari apa yang terjadi, kadang-kadang saya berhenti berdebat. Saat itu semua orang tergila-gila pada bagaimana kotak konten lebih baik daripada kotak perbatasan; itu adalah salah satu cara untuk menunjukkan kebencian terhadap IE. Kemudian datang bootstrap dan tiba-tiba semua orang percaya di perbatasan. Tren datang tetapi kemudian mereka pergi. Gunakan goto, gunakan tabel, gunakan iframe, ketahuilah apa yang Anda lakukan dan mengapa. Trendis akan mencoba menjatuhkan Anda, kemudian mereka mendaftar dan membayar di situs Anda. Dunia diselamatkan lagi.
dkellner
@dkellner Saya tidak mengerti bagian itu: "Server perlu tahu setidaknya jika seseorang masuk atau tidak. (Dan jika Anda mengganggu database setiap kali Anda perlu memutuskan ini, Anda praktis akan hancur.)". Katakanlah Anda menyimpan data sesi dalam database dengan PHP. Mengapa meminta DB untuk login tidak baik (dikutuk adalah kata yang kuat) karena bagaimanapun akan ada banyak permintaan DB berikutnya untuk mendapatkan data pengguna lengkap dan hal-hal lain, berdasarkan pada ID sesi PHP? Dengan kata lain, permintaan DB tidak bisa dihindari dalam kasus apa pun. Juga, jika Anda tidak menerima ID sesi PHP, Anda tahu pengguna tidak diauthentikasi, tidak perlu bertanya.
user2923322
Ketika Anda memiliki ribuan atau bahkan jutaan pengguna, Anda tidak dapat membayar kemewahan menghubungkan ke db setiap kali Anda ingin melakukan keepalive, pembaruan lokasi, jajak pendapat pesan, atau apa pun yang memerlukan check-in singkat. Anda harus mengimplementasikan panggilan-panggilan ini tanpa (atau dengan minimal) akses database, itu sebabnya saya katakan itu bisa mematikan jika Anda membangun seluruh konsep Anda di sekitar db. Sekali lagi, mungkin ada kasus di mana solusi db yang dirancang dengan baik akan bekerja, tetapi programmer khas akan menyelesaikan apa pun dengan mengatakan "oke, pertama kita terhubung dan mengambil beberapa info pengguna". Latihan Baaaad.
dkellner
3

Perbedaan utama antara stateless vs Stateful adalah data yang dikirimkan kembali ke server setiap saat. Dalam hal kewarganegaraan, klien harus memberikan semua informasi sehingga banyak parameter yang harus dilewati dalam setiap permintaan. Dalam Stateful, cliet melewati parameter tersebut sekali dan mereka dikelola oleh server sampai dimodifikasi oleh klien lagi.

IMO, API harus tanpa kewarganegaraan yang memungkinkan untuk meningkatkan dengan sangat cepat.

psuhas
sumber
2

Anda harus mengelola sesi klien di sisi klien. Ini berarti bahwa Anda harus mengirim data otentikasi dengan setiap permintaan, dan Anda mungkin, tetapi tidak perlu memiliki cache dalam-memori di server, yang memasangkan data auth ke informasi pengguna seperti identitas, izin, dll ...

Batasan kewarganegaraan REST ini sangat penting. Tanpa menerapkan batasan ini, aplikasi sisi server Anda tidak akan skala dengan baik, karena mempertahankan setiap sesi klien tunggal akan menjadi kelemahannya .

inf3rno
sumber
Jika Anda mengirim data auth dengan setiap permintaan, di mana / bagaimana Anda menyimpan kredensial pada klien sehingga pengguna tidak harus memasukkannya kembali pada setiap permintaan?
Amber
1

Saat Anda mengembangkan layanan RESTful, untuk dapat login Anda akan membutuhkan pengguna Anda untuk dikonfirmasi. Opsi yang memungkinkan adalah mengirim nama pengguna dan kata sandi setiap kali Anda berniat melakukan tindakan pengguna. Dalam hal ini server tidak akan menyimpan data sesi sama sekali.

Pilihan lain adalah untuk menghasilkan id sesi di server dan mengirimkannya ke klien, sehingga klien akan dapat mengirim sesi-id ke server dan mengautentikasi dengan itu. Ini jauh lebih aman daripada mengirim nama pengguna dan kata sandi setiap kali, karena jika seseorang mendapatkan data tersebut, maka ia dapat menyamar sebagai pengguna sampai nama pengguna dan kata sandi diubah. Anda dapat mengatakan bahwa bahkan id sesi dapat dicuri dan pengguna akan ditiru dalam kasus itu dan Anda benar. Namun, dalam hal ini menyamar sebagai pengguna hanya akan mungkin saat id sesi valid.

Jika RESTful API mengharapkan nama pengguna dan kata sandi untuk mengubah nama pengguna dan kata sandi, maka bahkan jika seseorang menyamar sebagai pengguna menggunakan id sesi, peretas tidak akan dapat mengunci pengguna yang sebenarnya.

Sesi-id dapat dihasilkan oleh penguncian satu arah (enkripsi) dari sesuatu yang mengidentifikasi pengguna dan menambahkan waktu ke id sesi, dengan cara ini waktu kedaluwarsa sesi dapat ditentukan.

Server mungkin atau mungkin tidak menyimpan id sesi. Tentu saja, jika server menyimpan id sesi, maka itu akan melanggar kriteria yang ditentukan dalam pertanyaan. Namun, penting untuk memastikan bahwa id sesi dapat divalidasi untuk pengguna yang diberikan, yang tidak mengharuskan penyimpanan id sesi. Bayangkan cara Anda memiliki enkripsi email satu arah, id pengguna, dan beberapa data pribadi khusus pengguna, seperti warna favorit, ini akan menjadi level pertama dan entah bagaimana menambahkan tanggal nama pengguna ke string terenkripsi dan menerapkan dua- enkripsi cara. Akibatnya ketika id sesi diterima, level kedua dapat didekripsi untuk dapat menentukan nama pengguna yang diklaim pengguna dan apakah waktu sesi tepat. Jika ini valid, maka tingkat enkripsi pertama dapat divalidasi dengan melakukan enkripsi itu lagi dan memeriksa apakah cocok dengan string. Anda tidak perlu menyimpan data sesi untuk mencapai itu.

Lajos Arpad
sumber
ini masuk akal
dimulai
0

Seluruh konsep berbeda ... Anda tidak perlu mengelola sesi jika Anda mencoba menerapkan protokol RESTFul. Dalam hal ini lebih baik untuk melakukan prosedur otentikasi pada setiap permintaan (sedangkan ada biaya tambahan untuk itu dalam hal kinerja - kata sandi hashing akan menjadi contoh yang baik. Bukan masalah besar ...). Jika Anda menggunakan sesi - bagaimana Anda bisa mendistribusikan beban di beberapa server? Saya yakin protokol RESTFul dimaksudkan untuk menghilangkan sesi apa pun - Anda tidak benar-benar membutuhkannya ... Itu sebabnya disebut "stateless". Sesi hanya diperlukan ketika Anda tidak dapat menyimpan apa pun selain Cookie di sisi klien setelah reqest dibuat (sebagai contoh, ambil browser lama yang mendukung Javascript / HTML5). Dalam kasus klien RESTFul "fitur lengkap" biasanya aman untuk menyimpanbase64(login:password) di sisi klien (dalam memori) hingga aplikasi masih dimuat - aplikasi digunakan untuk mengakses satu-satunya host dan cookie tidak dapat dikompromikan oleh skrip pihak ketiga ...

Saya akan merekomendasikan untuk menonaktifkan otentikasi cookie untuk layanan RESTFul ... periksa Basic / Digest Auth - yang seharusnya cukup untuk layanan berbasis RESTFul.

pengguna3857922
sumber
3
Apa itu a client side (in memory) dan bagaimana aman untuk menyimpan base64(login:password)di sisi klien?
RN Kushwaha
1
Tidak ada yang didefinisikan sebagai "sepenuhnya aman". Namun, Anda dapat mempertimbangkan untuk menggunakan OAuth2 yang memberikan keamanan yang lebih baik daripada menyimpan string base64 untuk permintaan API (Auth Dasar), jika Anda tetap menggunakan auth Dasar, Anda dapat menggunakan HTTPS untuk keamanan yang lebih baik.
felixwcf
3
RN Kushwaha, ini adalah pertanyaan yang sepertinya tidak seorang pun ingin menjawab ketika mereka meminta Anda untuk berhenti menyimpan sesi di server dan menyimpannya di klien.
BeniRose
0

REST tidak memiliki kewarganegaraan dan tidak mempertahankan status apa pun di antara permintaan. Cookie / tajuk klien diatur untuk mempertahankan status pengguna seperti otentikasi. Katakanlah nama pengguna / kata sandi Klien divalidasi oleh mekanisme otentikasi bagian ketiga - tingkat 2 OTP gerneation dll. Setelah pengguna diautentikasi - tajuk / cookie hadir untuk memulihkan titik akhir layanan yang terbuka dan kami dapat menganggap pengguna sebagai auth karena pengguna datang dengan tajuk / cookie yang valid . Sekarang info tertentu dari pengguna seperti IP disimpan dalam cache dan setelah itu jika permintaan berasal dari Ip (alamat mac) yang sama untuk sumber daya terdaftar, Pengguna diperbolehkan. Dan cache dipertahankan untuk beberapa waktu tertentu yang akan batal setelah penyimpangan waktu. Jadi cache bisa digunakan atau entri DB dapat digunakan untuk mempertahankan info dengan permintaan.

Amit
sumber
0

Stateless di sini berarti status atau meta data permintaan tidak disimpan di sisi server. Dengan mempertahankan setiap permintaan atau status pengguna di server, itu akan menyebabkan kemacetan kinerja. Server hanya diminta dengan atribut yang diperlukan untuk melakukan operasi tertentu.

Datang ke mengelola sesi, atau memberikan pengalaman khusus kepada pengguna, diperlukan untuk mempertahankan beberapa data meta atau keadaan preferensi pengguna, riwayat permintaan masa lalu. Ini dapat dilakukan dengan memelihara cookie, atribut tersembunyi atau menjadi objek sesi.

Ini dapat menjaga atau melacak status pengguna dalam aplikasi.

Semoga ini membantu!

Sourabh Bhavsar
sumber