セッションハイジャック防止用の質問の続きです。

http://q.hatena.ne.jp/1158727393
最新のアクセス時間を、サーバ側と、クッキー側に持たせるような Ajax のスクリプトがあるような気がします。例えば、1分ごとに時刻のデータ交換とチェックをサーバ側と、ブラウザ側で行います。データ交換の際には、最新のアクセス時刻がずれていないかを確認して、ずれていない場合には最新時刻を、サーバ、ブラウザ側で更新します。ずれている警告を出すか、ログアウトするようにします。
簡単なスクリプトだと思うので、サンプルがあるような気がします。非常に簡単なサンプルが欲しいのでできるだけ簡単なものお願いします。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2006/09/26 09:01:49
  • 終了:2006/10/03 09:05:08

回答(1件)

id:Kenju No.1

Kenju回答回数30ベストアンサー獲得回数22006/09/26 12:05:51

ポイント60pt

サーバ処理は、post送信された値を、セッションオブジェクトに保管していた値と同一かチェックして、同一なら現在時刻を取得してセット、同じ値を返す。

同一でなければセッションを切断してfalse文字列を返す。

クライアント処理は以下。serverURLを適当に変更してください。

ASP + IE6でテスト済みですが、他の環境でどうなるかわかりません。

<script type="text/javascript">
<!--

window.onload = function()
{
  var ajax = new AjaxObject(ajaxOnloadCheck);
  var serverURL = "http://session.asp";

  synchronizeServer();

  function synchronizeServer()
  {
    var synchroTime = Cookie.get("synchroTime");

    ajax.sendPost(serverURL, "time=" + synchroTime, false);
  }

  function ajaxOnloadCheck(responseText)
  {
    if(responseText == "false") {
      alert("セッションは切断されました。");
     } else {
      Cookie.set("synchroTime", responseText);
      setTimeout(synchronizeServer, 60000);
    }
  }

}

//Ajax用オブジェクト作成
function AjaxObject(onloadFunction, timeoutFunction, timeoutCount)
{
  this.ajax = this.create();
  this.timerID = null;

 //関数かどうかは実行時に評価。
  this.onload = onloadFunction;
  this.timeout = timeoutFunction;

  if(isFinite(timeoutCount))
    this.timeoutCount = timeoutCount;
   else
    this.timeoutCount = 0;
}

//XMLHttpRequestの作成。
AjaxObject.prototype.create = function()
{
  var ajaxObj = null;

 //IE以外
  if(window.XMLHttpRequest) {
    ajaxObj = new XMLHttpRequest();
  //IE用
   } else if(window.ActiveXObject) {
    try {
      ajaxObj = new ActiveXObject("Msxml2.XMLHTTP");
     } catch(e) {
      try {
        ajaxObj = new ActiveXObject("Microsoft.XMLHTTP");
      } catch(e) { }
    }
  }

  return ajaxObj;
}

//GET送信メソッド
AjaxObject.prototype.sendGet = function(url, synchronize)
{
  this.ajax.open("GET", url, synchronize);

 //イベントの設定
  var that = this;
  this.ajax.onreadystatechange = function(){that.onloadEvent();};
  if(this.timeoutCount > 0)
    this.timerID = setTimeout(function(){that.timeoutEvent();}, this.timeoutCount);

 //実際のファイルの取得
  this.ajax.send("");
}

//POST送信メソッド
AjaxObject.prototype.sendPost = function(url, sendString, synchronize)
{
  this.ajax.open("POST", url, synchronize);

 //イベントの設定
  var that = this;
  this.ajax.onreadystatechange = function(){that.onloadEvent();};
  if(this.timeoutCount > 0)
    this.timerID = setTimeout(function(){that.timeoutEvent();}, this.timeoutCount);

 //ヘッダのセット
  this.ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

 //実際のファイルの取得
  this.ajax.send(sendString);
}

//オンロード時イベント
AjaxObject.prototype.onloadEvent = function()
{
  if(this.ajax.readyState != 4 || this.ajax.status != 200)
    return false;

 //タイムアウト処理の中断。
  clearTimeout(this.timerID);

 //ユーザ定義イベントの実行。
  if(typeof this.onload == "function")
    this.onload(this.ajax.responseXML.hasChildNodes() ? this.ajax.responseXML : this.ajax.responseText);
}

//タイムアウト時イベント
AjaxObject.prototype.timeoutEvent = function()
{
 //取得の中断。
  this.ajax.abort();

 //ユーザ定義イベントの実行。
  if(typeof this.timeout == "function")
    this.timeout();
}

var Cookie = {

 //クッキーのセット。 durationの単位:日。
  set: function(key, value, duration) {
    var expiresStr = "";
    if(duration) {
      var date = new Date();
      date.setTime(date.getTime() + (duration * 86400000));
      expiresStr = "expires=" + date.toGMTString() + ";";
    }
    document.cookie = key + "=" + escape(value) + "; " + expiresStr;
  },

 //クッキーの取得
  get: function(key) {
    var tmp = "; " + document.cookie + ";";
    key = "; " + key + "=";
    var keyStart = tmp.indexOf(key, 0);
    var value = "";
    if(key.length > 0 &amp;&amp; keyStart >= 0) {
      var keyEnd = tmp.indexOf(";", keyStart + key.length);
      value = unescape(tmp.substring(keyStart + key.length, keyEnd));
    }
    return value;
  },

 //クッキーのクリア
  clear: function(key) {
    if(key == undefined || key == "") {
      var tmp = document.cookie.split(";");
      for(var ix = 0; ix < tmp.length; ix++) {
        key = tmp[ix].split("=")[0];
        this.set(key, "", -1);
      }
     } else {
      this.set(key, "", -1);
    }
  }

};

// -->
</script>

でも、クッキーの盗聴以外の方法でセッションハイジャックされる場合は大体他の方法で防げたと思います。

盗聴されるとまるで意味がないですから実用としてはどんなもんか疑問です。

http://q.hatena.ne.jp/

id:isogaya

>盗聴されるとまるで意味がないですから実用としてはどんなもんか疑問です。

そうですね。1分おきにやるとかいうのをいれれば、少しは安心かなと言う程度です。

2006/09/26 12:43:47

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません