Wednesday 11 February 2009

struts token kullanımı

aynı formu birden fazla submit etme, ya da back yapıp aynı formu tekrar submit etme gibi sorunları engellemek için struts'ta token kullandım. Bunun için google yaptiginizda back tuşunu engellemek gibi garip bir seçenek hakkında yogun bir tartisma görürsünüz. Fakat back yapmanın binbir yolu olduğundan ve kullanıcıyı kızdırmamak için, back işlevselliğine bulaşmamak daha iyi diye düşündüm. Ama yine de back tuşunu engelleme kodunu yazayım buraya. Bu kod ayrıca, input text alanı ya da textarea alanı içindeyken back tuşu işlevselliğini geri veriyor. Yani bu alanlarda back'i engellemiyor.

if (typeof window.event == 'undefined'){
document.onkeypress = function(e){
var fieldVal = e.target.nodeName.toUpperCase();

if (e.target.type)
var fieldType = e.target.type.toUpperCase();

if ((fieldVal == 'INPUT' && fieldType == 'TEXT') || fieldVal == 'TEXTAREA'){
return e.keyCode;
} else if (e.keyCode == 8) {
e.preventDefault();
}
}
} else {
document.onkeydown = function(){
var fieldVal = event.srcElement.tagName.toUpperCase();

if (event.srcElement.type)
var fieldType = event.srcElement.type.toUpperCase();
if ((fieldVal == 'INPUT' && fieldType == 'TEXT') || fieldVal == 'TEXTAREA'){
return event.keyCode;
}else if (event.keyCode == 8){
event.returnValue=false;
}
}
}


Bir diğer seçenek de location replace yapıp history'ye atılan değeri manipüle etmekti. Ama o da benim için uygun bir çözüm değildi.


Ve gelelim token konumuza.

Ders: Struts
Konu: Token


Token için kullanılan üç adet method var. saveToken(), isTokenValid() ve resetToken()

Forma gitmeden önce çağrılan metoda saveToken()'ı ekliyoruz. Böylece session'a unique bir key koymuş oluyoruz.

açılan jsp'yi view source yaparsak şuna benzer birşey görürüz:
<div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="e1473d05ed6b8a3ddf22844f94776dd2"></div>

Formu submit'inde çağrılan metoda da isTokenValid() i koyuyoruz. isTokenValid yaptığımız zaman, Submit ile formdan gelen key'i, session'daki key ile karşılaştırıyor ve form'un expire olup olmadığını anlıyor.

Son olarak, işlemimizin başarılı olduğu case'ler için resetToken çağırıyoruz ki yeni bir key oluştursun ve eski key expire olmuş olsun. Böylece, aynı form submit edildiğinde key'ler uyuşmadığından hata alınacak ve ikinci kez aynı işlemin yapılması engellenmiş olacak.

Eğer işlem başarılı olmamışsa yani hata alınmışsa resetToken'ı çağırmıyoruz, böylece mevcut key hala geçerli oluyor. Hata nedeniyle kullanıcı aynı formu tekrar submit etmek istediğinde key uyumsuzluğu yaşamıyor.

1 comment:

erhan said...

tüm actionların türediği bir BaseAction oluşturup, bu saveToken(), isTokenValid(), resetToken() metodlarını BaseAction içerisinden kontrol edildiği ve bizim de her action da bu işlemleri yapmak zorunda kalmadığımız bir BaseAction() oluştulabilir mi?