Bisakah Anda membantu saya memahami ini? “Kesalahan REST Umum: Sesi tidak relevan”

159

Penafian: Saya baru di sekolah pemikiran REST, dan saya mencoba membungkus pikiran saya dengannya.

Jadi, saya membaca halaman ini, Kesalahan REST Umum , dan saya merasa saya benar-benar bingung dengan sesi yang tidak relevan. Inilah yang dikatakan halaman:

Seharusnya tidak perlu bagi klien untuk "masuk" atau "memulai koneksi." Otentikasi HTTP dilakukan secara otomatis pada setiap pesan. Aplikasi klien adalah konsumen sumber daya, bukan layanan. Karena itu tidak ada yang bisa masuk! Katakanlah Anda memesan penerbangan pada layanan web REST. Anda tidak membuat koneksi "sesi" baru ke layanan. Alih-alih Anda meminta "objek pembuat jadwal" untuk membuat Anda jadwal perjalanan baru. Anda dapat mulai mengisi bagian yang kosong tetapi kemudian mendapatkan beberapa komponen yang sangat berbeda di tempat lain di web untuk mengisi bagian yang kosong lainnya. Tidak ada sesi sehingga tidak ada masalah kondisi sesi migrasi antara klien. Juga tidak ada masalah "afinitas sesi"

Oke, saya mendapatkan bahwa otentikasi HTTP dilakukan secara otomatis pada setiap pesan - tetapi bagaimana caranya? Apakah nama pengguna / kata sandi dikirimkan bersama setiap permintaan? Bukankah itu hanya meningkatkan luas permukaan serangan? Saya merasa seperti kehilangan bagian dari teka-teki.

Apakah buruk untuk memiliki layanan REST, katakanlah,, /sessionyang menerima permintaan GET, di mana Anda akan memasukkan nama pengguna / kata sandi sebagai bagian dari permintaan, dan mengembalikan token sesi jika otentikasi berhasil, yang kemudian bisa diteruskan dengan permintaan selanjutnya? Apakah itu masuk akal dari sudut pandang REST, atau apakah itu melewatkan intinya?

rampok
sumber
setiap permintaan selalu diautentikasi, pembajakan sesi adalah suatu hal. Tenang membuat ini lebih jelas tetapi tidak lebih terbuka.
Jasen

Jawaban:

79

Agar tenang, setiap permintaan HTTP harus membawa informasi yang cukup dengan sendirinya untuk penerimanya agar selaras sepenuhnya dengan sifat HTTP tanpa kewarganegaraan.

Oke, saya mendapatkan bahwa otentikasi HTTP dilakukan secara otomatis pada setiap pesan - tetapi bagaimana caranya?

Ya, nama pengguna dan kata sandi dikirim dengan setiap permintaan. Metode umum untuk melakukannya adalah otentikasi akses dasar dan otentikasi akses digest . Dan ya, seorang penguping dapat menangkap kredensial pengguna. Dengan demikian seseorang akan mengenkripsi semua data yang dikirim dan diterima menggunakan Transport Layer Security (TLS) .

Apakah buruk memiliki layanan REST, misalnya, / sesi, yang menerima permintaan GET, di mana Anda akan memasukkan nama pengguna / kata sandi sebagai bagian dari permintaan, dan mengembalikan token sesi jika otentikasi berhasil, yang dapat kemudian diteruskan bersama permintaan selanjutnya? Apakah itu masuk akal dari sudut pandang REST, atau apakah itu melewatkan intinya?

Ini tidak akan MENYENANGKAN karena ia menyatakan tetapi itu cukup umum karena itu kenyamanan bagi pengguna; seorang pengguna tidak harus login setiap kali.

Apa yang Anda gambarkan dalam "token sesi" biasanya disebut sebagai cookie masuk . Misalnya, jika Anda mencoba masuk ke akun Yahoo! akun ada kotak centang yang mengatakan "tetap masuk saya selama 2 minggu". Ini pada dasarnya mengatakan (dalam kata-kata Anda) "pertahankan token sesi saya hidup selama 2 minggu jika saya berhasil login." Browser web akan mengirimkan cookie masuk tersebut (dan mungkin yang lain) dengan setiap permintaan HTTP yang Anda minta untuk Anda buat.

z8000
sumber
5
Jawaban ini tidak masuk akal bagi saya. Pertama, dikatakan tidak masalah untuk memasukkan login dan kata sandi setiap kali dan juga sekali, yang masuk akal. Kemudian, ide untuk kembali ke klien kondisi login yang berhasil dalam bentuk token disarankan. Jika perlu, token dapat menyandikan waktu pembuatan. Kami tentu saja diperbolehkan untuk mengembalikan informasi kepada klien. Jadi, saran ini sepertinya baik untuk saya. Jawabannya mengatakan bahwa itu tidak baik karena "itu membawa negara," tetapi bukankah ide "ST" dalam "REST" bahwa negara dapat ditransfer di antara klien dan server?
33

Tidak jarang layanan REST memerlukan otentikasi untuk setiap permintaan HTTP. Sebagai contoh, Amazon S3 mensyaratkan bahwa setiap permintaan memiliki tanda tangan yang berasal dari kredensial pengguna, permintaan yang tepat untuk dilakukan, dan waktu saat ini. Tanda tangan ini mudah dihitung pada sisi klien, dapat dengan cepat diverifikasi oleh server, dan terbatas digunakan untuk penyerang yang mencegatnya (karena didasarkan pada waktu saat ini).

Greg Hewgill
sumber
3
+1 dapat Anda jelaskan pada: apakah penggunaan terbatas untuk penyerang yang mencegatnya (karena didasarkan pada waktu saat ini) ? bukankah Anda berbicara tentang cookie yang berisi nama pengguna dan kata sandi terenkripsi? seperti SO tidak? (IMHO)
Royi Namir
2
@RoyiNamir: Saya tidak berbicara tentang cookie. Tanda tangan yang digunakan oleh S3 adalah parameter untuk permintaan HTTP, tetapi bukan cookie, itu dihitung ulang untuk setiap permintaan.
Greg Hewgill
Jadi jika saya perlu menyimpan beberapa informasi tentang pengguna, di mana saya akan menyimpannya? dalam db? Saya tidak ingin pergi setiap permintaan ke db .... dan saya masih ingin menggunakan istirahat .... bisakah Anda membantu?
Royi Namir
@RoyiNamir: Jika Anda memiliki pertanyaan spesifik tentang cara mencapai beberapa tujuan, silakan ajukan pertanyaan baru . Saya tidak bisa menjawab pertanyaan tambahan di sini di komentar.
Greg Hewgill
10

Banyak orang tidak memahami prinsip-prinsip REST dengan sangat jelas, menggunakan token sesi tidak selalu berarti Anda stateful, alasan untuk mengirim nama pengguna / kata sandi dengan setiap permintaan hanya untuk otentikasi dan sama untuk mengirim token (dihasilkan oleh login proses) hanya untuk memutuskan apakah klien memiliki izin untuk meminta data atau tidak, Anda hanya melanggar konvensi REST ketika Anda menggunakan nama pengguna / kata sandi atau token sesi untuk memutuskan data apa yang akan ditampilkan! alih-alih, Anda harus menggunakannya hanya untuk penghentian (untuk menampilkan data atau tidak menampilkan data)

dalam kasus Anda, saya katakan YA ini RESTy, tetapi cobalah menghindari menggunakan sesi php asli di API REST Anda dan mulai menghasilkan token hash Anda sendiri yang kedaluwarsa dalam periode waktu yang ditentukan!

EvilThinker
sumber
1
Terima kasih. mengapa orang harus menghindari sesi php asli dan menggunakan token hash sendiri sebagai gantinya?
Matius
tidak ada alasan brilian yang saya katakan, hanya untuk keamanan yang lebih dan kontrol yang lebih besar.
EvilThinker
Ini lebih baik daripada jawaban yang diterima. Paling tidak, ia menerima saran sebagai RESTY, yang masuk akal. Namun, saya tidak melihat mengapa informasi yang dikirimkan tidak dapat digunakan untuk melakukan otorisasi yang bergantung pada pengguna. Beberapa pengguna mungkin memiliki akses ke beberapa data dan yang lain tidak. Itu tidak membuat protokol non TENANG.
8

Tidak, tidak ada salahnya. ClientLogin Google bekerja dengan cara ini persis dengan pengecualian bahwa klien diperintahkan untuk pergi ke "/ sesi" menggunakan respons HTTP 401. Tetapi ini tidak membuat sesi, itu hanya menciptakan cara bagi klien untuk (sementara) mengotentikasi diri mereka sendiri tanpa melewati kredensial secara jelas, dan bagi server untuk mengontrol validitas kredensial sementara ini yang dianggap sesuai.

mogsie
sumber
11
@ unforgiven3. Selama token yang dikembalikan hanya digunakan untuk mengotentikasi pengguna dan tidak digunakan oleh server untuk mengaitkan pengguna ke negara lain yang disimpan di server, maka saya melihat tidak ada kendala REST yang dilanggar.
Darrel Miller
4
@ unforgiven3 Token yang dikembalikan oleh server, pada dasarnya, membuktikan bahwa pengguna adalah yang mereka katakan. Jadi, alih-alih setiap permintaan termasuk nama pengguna dan kata sandi, setiap permintaan menyertakan token yang dibuat sedemikian rupa sehingga server dapat yakin akan kebenarannya.
Darrel Miller
1
@ unforgiven3, Darrel benar. Token yang digemakan kembali harus dikirim oleh klien pada setiap permintaan HTTP, seperti halnya pada otentikasi dasar, intisari, hingga token berakhir. Ketika itu terjadi, klien dapat mengulangi login, secara opsional meminta kredensial pengguna, atau apa pun. Saya bisa menguraikan jawabannya, jika Anda mau. sunting: (Dan terima kasih telah mengikuti jawaban atas pertanyaan lama!)
mogsie
1
Tidak masalah, mogsie, selalu menarik untuk membahas hal-hal seperti ini :-) Saya rasa saya melihat ke mana Anda akan pergi dengan ini, sayangnya saya tidak cukup mengerti tentang intisari digest untuk benar-benar memahami ini (kebanyakan saya hanya tidak memahami bagaimana token dikirim kembali setiap permintaan HTTP, tetapi itu tampaknya merupakan detail implementasi). Namun, saya sekarang mengerti mengapa metode ini tidak melanggar prinsip REST. Terima kasih atas tanggapannya!
Rob
6
@ unforgiven3, Ini bisa membantu: token adalah informasi yang sudah ditandatangani. Jadi itu serba lengkap. Server dapat memvalidasi token tanpa memeriksa keadaan yang sebelumnya disimpan. Jadi itu hanya keadaan yang disimpan di klien dan ditransfer bolak-balik.
Iravanchi
5

Oke, saya mendapatkan bahwa otentikasi HTTP dilakukan secara otomatis pada setiap pesan - tetapi bagaimana caranya?

"Otorisasi:" tajuk HTTP dikirim oleh klien. Baik dasar (teks biasa) atau intisari.

Apakah buruk memiliki layanan REST, misalnya, / sesi, yang menerima permintaan GET, di mana Anda akan memasukkan nama pengguna / kata sandi sebagai bagian dari permintaan, dan mengembalikan token sesi jika otentikasi berhasil, yang dapat kemudian diteruskan bersama permintaan selanjutnya? Apakah itu masuk akal dari sudut pandang REST, atau apakah itu melewatkan intinya?

Seluruh ide sesi adalah membuat aplikasi stateful menggunakan stateless protocol (HTTP) dan dumb client (browser web), dengan mempertahankan status di sisi server. Salah satu prinsip REST adalah "Setiap sumber daya dialamatkan secara unik menggunakan sintaksis universal untuk digunakan dalam tautan hypermedia" . Variabel sesi adalah sesuatu yang tidak dapat diakses melalui URI. Aplikasi Sungguh RESTful akan mempertahankan keadaan di sisi klien, mengirim semua variabel yang diperlukan melalui HTTP, lebih disukai di URI.

Contoh: cari dengan pagination. Anda akan memiliki URL dalam formulir

http://server/search/urlencoded-search-terms/page_num

Ini memiliki banyak kesamaan dengan URL yang dapat di-bookmark

vartec
sumber
4
Informasi otentikasi juga tidak dapat diakses melalui URI - semua orang berbicara tentang mengirim info auth sebagai bagian dari header permintaan. Apa bedanya dengan menyertakan token sesi dengan permintaan? Saya tidak mengatakan menggunakan token sesi di URI, tetapi dalam data yang dikirimkan dalam permintaan.
Rob
Otentikasi ditetapkan jika Anda diizinkan untuk melakukan tindakan itu, dan dalam aplikasi RESTful tidak akan memengaruhi hasilnya.
vartec
4
Token sesi juga ditetapkan jika Anda berwenang untuk melakukan tindakan itu. Apa maksud Anda itu tidak akan mempengaruhi hasil itu? Jika penelepon tidak diotorisasi, mereka mendapatkan kesalahan Tidak Diotorisasi. Hal yang sama dengan token sesi. Saya benar-benar tidak melihat perbedaannya?
Rob
3
Tidak, token sesi adalah pegangan untuk menyatakan disimpan di server. Itu tidak tenang. Adapun yang Tidak Diotorisasi, saya tidak melihat itu sebagai hasilnya. Saya lebih suka mempertimbangkan pengecualian (seperti dalam coba / tangkap).
vartec
Cukup adil, vartec - itu masuk akal. Terima kasih atas tindak lanjutnya!
Rob
3

Saya pikir saran Anda baik-baik saja, jika Anda ingin mengontrol waktu sesi sesi klien. Saya pikir arsitektur RESTful mendorong Anda untuk mengembangkan aplikasi stateless. Seperti @ 2pence menulis "setiap permintaan HTTP harus membawa informasi yang cukup dengan sendirinya untuk penerimanya agar selaras sepenuhnya dengan sifat HTTP yang tanpa kewarganegaraan" .

Namun, tidak selalu demikian, terkadang aplikasi perlu memberi tahu kapan klien log-in atau log-out dan untuk mempertahankan sumber daya seperti kunci atau lisensi berdasarkan informasi ini. Lihat pertanyaan tindak lanjut saya untuk contoh kasus seperti itu.

LiorH
sumber