Çıkış: GET veya POST?


434

Bu soru genel olarak GET veya POST'un ne zaman kullanılacağı ile ilgili değildir; bir web uygulamasında oturum açmak için hangisinin önerildiği ile ilgilidir. Genel anlamda GET ve POST arasındaki farklar hakkında bol miktarda bilgi buldum, ancak bu özel senaryo için kesin bir cevap bulamadım.

Bir pragmatist olarak, GET kullanmaya meyilliyim, çünkü onu uygulamak POST'tan çok daha basit; basit bir bağlantı bırakın ve işiniz bitti. Bu, en azından kafamın üstünden düşünebileceğim web sitelerinin büyük çoğunluğunda durum gibi görünüyor. Yığın Taşması bile GET ile oturumu kapatır.

Beni tereddüt ettiren şey, bazı web hızlandırıcılarının / proxy'lerinin sayfada buldukları her bağlantıyı alıp alarak önbellekleri önbelleğe aldıkları iddiasıdır, böylece kullanıcı tıkladığında daha hızlı yanıt alır. Bunun hala geçerli olup olmadığından emin değilim, ancak bu durumda, teoride bu hızlandırıcılardan birine sahip bir kullanıcı, oturum açtığı anda uygulamadan atılacaktı, çünkü hızlandırıcısı oturumunu bulacak ve alacaktı bağlantıyı hiç tıklamadı bile.

Şimdiye kadar okuduğum her şey POST'un "yıkıcı eylemler" için kullanılması gerektiğini, oysa uygulamanın benzeri sorgulamanın iç durumunu değiştirmeyen eylemlerin GET ile ele alınmasını önermektedir . Buna dayanarak, buradaki gerçek soru:

Bir uygulamadan çıkış yapmak yıkıcı bir eylem olarak mı görülüyor / uygulamanın dahili durumunu değiştiriyor mu?


Siteyi ilk kez ziyaret ettiğinizi ve çıkış bağlantısının mevcut olmadığını varsayarsanız, giriş yaptığınızda oturumu kapatırsınız. Çıkış URL'si zaten önbelleğe alınmış olduğundan, ikinci kez giriş yaptıktan sonra iyi olur. Ancak, herhangi bir iyi hızlandırıcının çoğu çıkış URL'sini filtreleyebileceğini varsayabiliriz.
HyperCas

2
HyperCas, çıkış URL'lerini filtreleyen hızlandırıcılar, düşündüğüm bir teoriydi ve soruyu göndermeye karar vermemin nedenlerinden biri. Sadece hızlandırıcı mantığına güvenmek konusunda biraz isteksiz hissediyorum ve bir gün boktan bir hızlandırıcıya sahip bir kullanıcının giriş yapamayacağından şikayet etmesini istiyorum. Bir standarda uyup uymadıklarını veya böyle bir standardın mevcut olup olmadığını biliyor musunuz?
Daniel Liuzzi

Otomatik olarak bir form gönderen herhangi bir Hızlandırıcı (örneğin) kötü amaçlı bir IMO olacaktır ... Bir hızlandırıcının bir formu otomatik olarak göndereceğini düşünmek tamamen mantıksızdır. Google'ı ziyaret ettiğinizi düşünün. Arama formunu nasıl gönderebilir? Hiç kimse Malware'i çok öngörülemez olduğu ve kurallara uymadığı için açıklayamaz.
Alex

3
@AlexW - Sanırım sorumu yanlış anladın. Önerdiğim hızlandırıcı senaryosu, POST değil GET kullanırken olası bir sorunu göstermektir;
Daniel Liuzzi

1
Bunun için çok geç olduğumu anlıyorum, ama Alex, Daniel'in istediği bu değil. Bir kullanıcı oturum kapatma bağlantısını tıklatırsa ve bir hızlandırıcı, önbelleğe alınmış oturum kapatma sayfasını uygulamaya çarpmadan geri döndürürse, kullanıcının oturum açmaya devam edeceğini söyler. her neyse.
Rob Grant

Yanıtlar:


475

Kullanın POST.

2010 yılında, kullanmak GETmuhtemelen kabul edilebilir bir cevaptı. Ancak bugün (2013'te) tarayıcılar, bir sonraki ziyaret edeceğinizi düşündükleri sayfaları önceden getirecek.

Twitter'da bu sorun hakkında konuşan StackOverflow geliştiricilerinden biri:

GET isteğinden çıkış yapan bankamıza ve kullanışlı URL önceden getirme için Chrome ekibine teşekkür etmek istiyorum. - Nick Craver ( @Nick_Craver ) 29 Ocak 2013

eğlenceli gerçek: StackOverflow, GET üzerinden çıkış yapmak için kullanılır, ancak artık kullanılmaz.


2
Bu güncelleme için teşekkürler Dave. SO'yu POST'a çevirdiğini fark etmedim ve dürüstçe Chrome'un önceden getirme ile birlikte geldiğine dair hiçbir fikrim yoktu. Son olarak, alıntıladığınız twit, benim tarif ettiğim soruna asla daha iyi bir örnek sunamazdı. sorum ve şüphelerimi doğruluyor. Cevabınızı oyluyorum ve kabul edilen cevabı yapıyorum.
Daniel Liuzzi

4
Tarayıcımda, Stackoverflow oturumu kapatma bir POET değil, bir GET olan <li> <a href="https://stackoverflow.com/users/logout"> çıkış </a> </li> gibi görünüyor
boatcoder 22:13

9
@ Mark0978 bağlantısını tıklayın.
David Murdoch

2
İlginç. Muhtemelen en az favori özelliklerimden biri, daha sonra emin olup olmadığımı soran bir çıkış. Tahmin edin, ön getirmenin oturumunuzu kapatmasını önler, ancak Amazon, Ebay ve Gmail, kullanıcının söylendiği şey oturumdan çıkma ile gerçek oturum kapatma olayı arasında bu hile sayfası olmadan çıkış için GET kullanır. Sayfa arasında birçok kişinin yanlışlıkla oturumu kapattığına inanmasına yol açacağını düşünürüm. SO'daki problemler minimaldir, para dahil değildir ve her şeyin% 99'u zaten kamuya açıktır.
boatcoder

7
@Red HTTP / 1.1 standardına göre, bu tarayıcının değil, sunucunun hatasıdır. GET'in sunucu tarafında herhangi bir yan etkisi olması beklenmemektedir. Standart, "kullanıcı yan etkileri talep etmediğinden, bu nedenle kendilerinden sorumlu tutulamaz" diyor.
eyuelt

45

REST'te oturum olmamalıdır, bu nedenle yok edilecek bir şey yoktur. Bir REST istemcisi her istekte kimlik doğrulaması yapar. Giriş yaptınız veya çıktınız, sadece bir yanılsama.

Gerçekten sorduğunuz şey, tarayıcının her istekte kimlik doğrulama bilgilerini göndermeye devam etmesi.

Muhtemelen, uygulamanız giriş yapma yanılsaması yaratıyorsa, javascript kullanarak "çıkış" yapabilmeniz gerekir. Gidiş dönüş gerekmez.


Saha Çalışması - Bölüm 5.1.3

istemciden sunucuya yapılan her istek, isteği anlamak için gerekli tüm bilgileri içermelidir ve sunucuda depolanan herhangi bir bağlamdan yararlanamaz. Dolayısıyla oturum durumu tamamen istemcide tutulur


1
Aslında bunun farkında değildim. Sonra FormsAuthentication ile ASP.NET MVC kullanıyorum ve oturumları dayanıyor gibi benim app hiç çok RESTful olmayacak sanırım
Daniel Liuzzi

19
ancak pratikte giriş bilgileri httponlybazı xss risklerini önlemek için öznitelik ile işaretlenmiş bir çerezde tutulur, bu da sadece sunucudan sıfırlanabileceği anlamına gelir (çerezi manuel olarak temizlemekten kısadır)
Remus Rusanu

6
Kullanıcıdaki gibi 'Manuel' Tarayıcı ayarlarına gider ve 'Çerezleri temizle' seçeneğini belirler. Bir web sitesinde 'oturumu kapatmanın' kabul edilemez bir yolu.
Remus Rusanu

1
@Remus Ahhh, ünlü web tarayıcısının web uygulamaları yazmayı nasıl bu kadar acı verici hale getirdiğini.
Darrel Miller

1
@DarrelMiller evet ancak sunucu tarafında bir JWT'yi iptal etmemek bir güvenlik açığıdır. Jetonlar sunucuda depolanmasa bile, bir kullanıcı kötüye kullanımı önlemek için oturumları kapattığında / parolaları değiştirdiğinde / rolleri / çıkışları değiştirdiğinde (en azından süresi dolana kadar) kara listeye alınmalıdır.
java-addict301

38

GETBurada kötüye kullanımın bir yolu , bir kişinin (belki de :) src="<your logout link>"internette HER YERDE bir resim etiketi yerleştirmiş olması ve sitenizin bir kullanıcı bu sayfada tökezlemesi durumunda, bilmeden çıkış yapmasıdır.


4
Hayır, bu doğru değil. Oturumu kapatma bağlantısı, yalnızca başka bir etki alanından olmayacak doğru çerez verileri gönderilirse çalışır. Ve oturum kimliği url'de saklansa bile, bu her oturum için bu değişiklik olarak çalışmaz.
Richard H

4
Vay canına, bunu hiç düşünmemiştim! Yani, GET'i kullanmamanın bir başka nedeni ve neden herkesin bunu yaptığını anlamıyorum. Kahretsin, şimdi bir stackoverflow.com/users/logout "image" da yazımı eklemek ve ne olacağını görmek için cazip geldim:
Daniel Liuzzi

24
src = basit bir tarayıcı isteğidir, sunucu tarafından değil istemciden gelir. Tüm çerezleri taşır ve kullanıcı IP'sinden gelir. Bu nedenle reklam izleme pikselleri çalışır. Bu tür bir istismarın belirlenmesinin tek yolu yönlendireni kontrol etmektir.
raveren

12
SuperLogout.com tam olarak bunu yapar ( /logoutURL'leri gizli görüntülere yükle ) ve çalışır.
Dan Dascalescu

9
re: SuperLogout ... Bunu neden tıkladığımı bilmiyorum.
MI Wright

21

Doğru olmak gerekirse, GET / POST (veya diğer fiiller) bazı kaynaklardaki eylemlerdir (URL ile adreslenir) - bu nedenle genel olarak kaynağın durumu ile ilgilidir ve uygulama durumu ile ilgili değildir. Bu nedenle, gerçek ruhlarda, [host name]\[user name]\session'DELETE', oturumu kapatma işlemi için doğru fiil gibi bir URL'ye sahip olmalısınız .

[host name]\bla bla\logoutGerçekten bir REST tam yolu (IMO) olarak URL olarak kullanmak , neden GET / POST'un doğru kullanımı hakkında tartışalım?

Tabii ki, ben de benim uygulamalarımda oturum kapatma url GET kullanın :-)


2
Bu durumda, kullanıcıların [oturum adı] kısmına sahip olmanın gereksiz göründüğünü, kullanıcıların her zaman kendi oturumlarından çıkış (örn. DELETE) yaptıklarını ; asla diğer kullanıcıların :-)
Daniel Liuzzi

1
Aslında değil - oturumun bir kaynak olduğunu söylüyoruz ve silmek istiyoruz. Bu nedenle, herhangi bir oturumu tek başına ele almak için URL'nin bir parçası olarak kullanıcı adınızın olması gerekir. Argümanınız [fotoğraf galerisi] \ resimlerinde PUT eylemi yayınlamak demek, fotoğraflarınıza eklediğiniz anlamına gelir ([fotoğraf galerisi] \ [kullanıcı adı] \ resimlerde mevcut). Farklı kaynakların açık bir şekilde ele alınması gerekir, bunun içinde herhangi bir dolaylılık olamaz. Site, diğer kullanıcıların galerinize resim eklemesine izin verebilir - tıpkı herkesin oturumlarını öldürebilen bir süper kullanıcıya sahip olabileceğiniz gibi erişim kontrolünün bir parçası olacaktır.
VinayC

1
Felsefi olarak, oturumlara ve fotoğraflara 'kaynak' diyebilirsiniz, ama gerçekçi olarak onlara aynı şekilde davranmazdım. Oturum her zaman gerçek kullanıcıyla (dolayısıyla Oturum adı) sınırlıdır ve en azından ASP.NET'te başka bir kullanıcının oturumlarına erişmenin bir yolu yoktur. Uygulama geliştiricinin bile tüm aktif oturumları numaralandırmanın doğrudan bir yolu yoktur veya oturumları ayrı ayrı öldürmek için araçlar yoktur. Tüm oturumları (InProc) öldürmek için uygulamayı yeniden başlatabilirsiniz, ancak bu erişim denetimini çağırmam. URL'ler bir yana, soru hala devam ediyor: GET veya POST?
Daniel Liuzzi

Kaynak, dolayısıyla adresi (URL) REST'in önemli bir parçasıdır. Dediğim gibi URL'yi seçerseniz, DELETE, GET veya POST değil, doğru sözcük olur. Ayrıca, kendinizi ASP.NET ile sınırlasanız bile, her zaman özel durum sağlayıcınızın oturumları numaralandırmanıza ve gerekirse diğer oturumları öldürmenize olanak tanıyan her zaman sahip olabilirsiniz. Kullanıma hazır oturum içi oturumlar için global.asax'taki bazı işlemler size işlevsellik kazandırmalıdır. Bu gerçekten böyle bir işlevin gerekli olup olmayacağı sorusudur. Sık olmayan ihtiyaçlar için, insanlar insanları siteden çıkarmak için web sitesini yeniden başlatma eğilimindedir.
VinayC

Bu benim için en anlamlı. Web api'ye bir oturum yolu verin ve üzerinde DELETE çağırın. ../Session veya ../session/current olsun. @VinayC
Simon Hooper

16

Oturumu kapatmak uygulamanın kendisine hiçbir şey yapmaz. Kullanıcının uygulama ile ilgili durumunu değiştirir. Bu durumda, sorunuzun bu eylemi başlatmak için komutun kullanıcıdan nasıl başlatılması gerektiğine bağlı olduğu anlaşılmaktadır. Bu bir "yıkıcı eylem" olmadığından, oturumun terk edildiğinden veya yok edildiğinden emin olun, ancak uygulamanızın veya verilerinizin değiştirilmediğinden, her iki yöntemin bir oturum kapatma prosedürü başlatmasına izin vermek mümkün değildir. Gönderi, kullanıcı tarafından başlatılan herhangi bir işlem tarafından kullanılmalıdır (örn. - kullanıcı "Oturumu kapat" ı tıklar), get, uygulama tarafından başlatılan çıkışlar için ayrılabilir (örn., Olası kullanıcı saldırılarının oturum kapatma GET'i ile giriş sayfasına zorla yeniden yönlendirmelerini algılayan bir istisna ).


İlginç; Hiç böyle düşünmemiştim. +1.
Strager

Bu, muhtemelen uygulamaya (bir tür "basamaklı silme" davranışı) bağlı olabilir, ancak haklısınız.
Andres Jaan Tack

@JoelEtherton Teşekkür ederim Joel, doğru olana ne zaman ulaşacağımı merak eden cevapları okuyordum. :)
Kirill Fuchs

4
Bu kafa karıştırıcı çünkü çıkış durumu değiştiriyor. POST, durumu değiştirmek için fiildir. GET vatansız veri almak içindir. Bu kafa karıştırıcı çünkü POST isteklerinin yükleri olmasını bekliyoruz. Aşağıda belirtildiği gibi, DELETE bir oturum nesnesinde en doğru olur.
Michael Cole

1
@MichaelCole: POST ve GET arasındaki zorlukların temsiline katılıyorum. Yine de DELETE fiilinin kullanımı ile aynı fikirde değilim. DELETE bir kaynağı işlemek içindir ve oturum bu anlamda bir kaynak değildir. SİLİNEBİLİRSİN, bunu da KOYMALISIN.
Joel Etherton

16

Benim görüşüme göre merhaba, giriş yaptığınızda kullanıcı adını / şifreyi kontrol edersiniz ve eğer eşleşiyorsa giriş kodunu yaratırsınız.

CREAT belirteci => yöntem POST

Oturumu kapattığınızda jetonu dağıtıyorsunuz, böylece bana en mantıklı yöntem bir DELETE olmalı

DELETE token => yöntem DELETE


4
İlginç açı.
Drumbeg

1
Spring Boot REST uygulamalarımda bu yöntemi kullanıyorum.
Lütfen

1
anlamsal olarak doğru. Kabul ediyorum ...
DAG

1

Önbelleğe alma senaryosu ilginçtir. Ama eğer pek çok site inc SO bu konuda endişelenmeyin, o zaman belki de değil gerektiğini tahmin ediyorum.

Ya da bağlantı javascript'te uygulanabilir mi?

Düzenleme: Anladığım kadarıyla, teknik olarak bir GET, uygulama durumunu değiştirmeyen salt okunur istekler için olmalıdır. POST, durumu değiştiren yazma / düzenleme istekleri için olmalıdır. Bununla birlikte, diğer uygulama sorunları bazı eyalet değiştiren istekler için POST yerine GET'i tercih edebilir ve bununla ilgili herhangi bir sorun olduğunu düşünmüyorum.


Teşekkürler. DB durumu değiştirilemez, ancak oturum durumu olur. Gördüğüm tek sorun, kullanıcıların dışarı atılmalarıyla ilgili soruda bahsettiğim sorun. Tahribatsız ama oldukça can sıkıcı. Ben genellikle "büyük adamlar yaparsa, o zaman Tamam olmalı" mantra tarafından gitmek. Sadece başkalarının bu konuda ne düşündüğünü bilmek istedim.
Daniel Liuzzi

0

Web uygulamanızın oturumu bir oturum kapatma komut dosyası aracılığıyla terk etmesine izin verirseniz, genellikle ikisine de ihtiyacınız yoktur. Normalde, terk edilmesini istediğiniz oturum için benzersiz olan bir oturum değişkeni vardır.


"Oturumu kapat komut dosyası" nı hazırlayabilir misiniz? Bir çerez sona erme tarihi ayarlamaya atıfta bulunduğunuzdan emin değilim (bu, kullanıcıların manuel olarak çıkış yapmalarına izin verme yolunu ortadan kaldırmaz.)
Daniel Liuzzi

Oturumu kapatma komut dosyası kullanıcının (aslında: tarayıcı) oturumunu sonlandıracaktır. ASP.net, oturum terk edilebilir bir sunucu tarafı nesnesidir. PHP de benzer bir sisteme sahiptir. Bu tarayıcı oturumu sonlandıran komut dosyasını çağırdığı için hangisinin biteceğini zaten bilir ve POST veya GET değişkenlerine olan ihtiyacı ortadan kaldırır.
Rob

1
Evet, şimdi anladım. Zaten özellikle yerinde FormsAuthentication.SignOut () komut dosyası var, ama benim sorum hakkında nasıl GET veya POST gibi senaryoyu çağırmak için.
Daniel Liuzzi

Url formunda mı? Herhangi bir bilgi iletmemeniz önemli değil. Olabilecek en kötü şey, komut dosyasını el ile açan ve oturumu kapatan birisidir. Gerekli olmasa bile bir form alanı yapmazdım, komut dosyasına bir bağlantı da işe yarardı. Komut dosyasına bilgi gönderirseniz, kullanıcıya herhangi bir bilgi göstermemek için muhtemelen bir POST'a giderim (sayfa kaynağını görüntülemedikleri sürece) ve yenilendikleri takdirde tarayıcılarından bir uyarı alırlar (sayfa süresi doldu).
Rob

0

Son zamanlarda Oturumu Kapatmak için GET kullandığım bir proje üzerinde çalışıyordum Aşağıda Nodejs Express'teki kod var ve mükemmel çalışıyor

yönlendiriciniz.

const express = require("express");
router.get("/signout", signout);

controller.js'niz

exports.signout  = (req, res) => {
        res.clearCookie('t'); //clearing cookie, which is 
            //assign to the user during sign in.          
            res.json({message : 'Signout success'});   
        };

-2

Çıkış yapmanın (kullanıcı izinlerini kaldırma) nasıl yapıcı bir eylem olduğunu görmüyorum. "Çıkış" eylemi yalnızca önceden oturum açmış olan kullanıcılar tarafından kullanılabilir olması gerektiğinden, bu işlem eski olur.

Tarayıcı çerezlerinizde bulunan rastgele oluşturulmuş bir dize, kullanıcı oturumunuzu temsil eder. Bunu yok etmenin tonlarca yolu vardır, bu yüzden oturumunuzu kapatmak, ziyaretçinize sadece bir hizmettir.


2
wgetÖrümcek modunda, özel bir wiki'de doğru oturum çerezi ile bir kez yapmak zorunda olduğum bir şeydi. Tabii ki, ilk taranan URL'lerden biriydi /logout.
Helgi

5
SuperLogout.com'a giderek /logoutsayfalara yıkıcı GET isteklerinin gerçekten ne kadar olduğunu görün . Örneğin, Gmail'de tekrar oturum açmanız, tekrar sohbette oturum açmanız, kaydırdığınız Hangouts görüşmelerinde yerinizi bulmanız vb. - ve bu yalnızca Google.com içindir.
Dan Dascalescu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.