セッションの有効期限が切れると自動ログオフ
-
12-09-2020 - |
質問
アプリケーションは 30 分後にログオフし、ログイン ページにリダイレクトされます。web.xml でセッション タイムアウトを指定し、リダイレクトに requestProcessor を使用しています。セッションの有効期限が切れたら、セッションが期限切れになったことを示すメッセージをユーザーに表示したいのですが、方法自動ログオフしてもいいですか?ページに「セッションがタイムアウトしました。もう一度ログインしてください」というエラー メッセージを表示したいと考えています。では、セッションのタイムアウトを検出するにはどうすればよいでしょうか?メソッドは自動的にトリガーされますか?
解決
ユーザのアクティビティが起こった場合は毎分チェックするアクティビティチェッカーを作成し(MouseClick、Keypress)、ユーザーがアクティブなときにセッションを生き続けるためにサーバー側にハートビートを実行し、ユーザーがアクティブでないとき何もしません。。30分間のアクティビティがない場合(またはサーバー側にデフォルトのセッションタイムアウトが設定されているものがすべてです)、リダイレクトを実行します。
これは、 jquery のほとんど助けを持つキックオフの例です。
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$.active = false;
$('body').bind('click keypress', function() { $.active = true; });
checkActivity(1800000, 60000, 0); // timeout = 30 minutes, interval = 1 minute.
});
function checkActivity(timeout, interval, elapsed) {
if ($.active) {
elapsed = 0;
$.active = false;
$.get('heartbeat');
}
if (elapsed < timeout) {
elapsed += interval;
setTimeout(function() {
checkActivity(timeout, interval, elapsed);
}, interval);
} else {
window.location = 'http://example.com/expired'; // Redirect to "session expired" page.
}
}
</script>
.
Servlet
を聴取する/heartbeat
を作成し、基本的に以下のものだけを行います。
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
request.getSession();
}
.
セッションを生き続けるために。
ログインユーザーをセッションに保存すると、セッションが期限切れになるたびに「自動的に」ログアウトされます。そのため、手動でユーザーにログアウトする必要はありません。
他のヒント
HttpSessionListener
を実装し、web.xml セッションが破壊されたときにあなたに通知されます。sessionDestroyed()
メソッドを使用してください。
ここでの詳細を参照してください。
http://www.mkyong。COM /サーブレット/ a-simple-httpSessionListener-example-active-sessions-counter /
単純なサーブレット、spring-mvc、または spring-security のいずれかである可能性があり、完全なクライアント側ロジックがなければ自動ログアウトは不可能です。
申請には両方のタイプのリクエストが含まれることを検討しています
- AJAXと
- フォームの送信/ページのリロード
自動ログアウトには非常に計算されたロジックが必要です。次のような自動ログアウト機能の実装を示します。
利点。
1.これを実現するために追加の呼び出し/リクエストは使用されません。10,000 を超えるアクティブ ユーザーと自動ログアウトを実現するための追加の呼び出しによるパフォーマンスへの影響を考慮します。
2.タグを使用した1行構成。
3.ユーザーが複数のタブや複数のウィンドウを開いた場合でも、問題なく動作します。
4.セッションが無効になる 30 秒前に通知されるため、フォームに記入して送信しなかった場合でも、セッションを維持できます (ワンクリックでセッションを延長)。したがって、ユーザーは保存されていないデータを失う可能性が低くなります。
使用法
1.以下に示すように、必要な JSP ページに自動ログアウト スクリプトを含めます。
....
</body>
<jsp:include page="../template/autologout-script.jsp"></jsp:include>
</html>
2.JSP ページ autologout-script.jsp を作成し、以下のコードを追加します。注記:編集/設定は必要ありません
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<script>
$(document).ready(function()
{
var timeOutTimeInSeconds = ${ timeOutTimeInSeconds };
var showTimerTimeInSeconds= ${ showTimerTimeInSeconds };
var sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
var timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
var badgeTimerId;
window.localStorage.setItem("AjaxRequestFired", new Date());
function redirectToLoginPage(){
//location.href = '<c:url value="/" />'+'${loginPageUrl}';
window.location.reload();
}
$(document).ajaxComplete(function () {
resetTimer();
});
$(window).bind('storage', function (e) {
if(e.originalEvent.key == "AjaxRequestFired"){
console.log("Request sent from another tab, hence resetting timer")
resetTimer();
}
});
function resetTimer()
{
showTimerTimeInSeconds= ${ showTimerTimeInSeconds };
console.log("timeOutTimeInSeconds : "+timeOutTimeInSeconds)
window.localStorage.setItem("AjaxRequestFired", new Date());
window.clearInterval(sessionCheckIntervalId);
sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
window.clearInterval(timerDisplayIntervalId);
timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
hideTimer();
}
function showTimer()
{
$('#sessionTimeRemaining').show();
$('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
window.clearInterval(timerDisplayIntervalId);
badgeTimerId = setInterval(function(){
$('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
}, 1000);
}
function hideTimer()
{
window.clearInterval(badgeTimerId);
$('#sessionTimeRemaining').hide();
}
});
</script>
3.セッション属性を構成してタイムアウト設定を構成する注記:セッション作成後にこれを設定します。HttpSessionListener sessionCreated メソッドを実装し、要件に応じて次の構成を設定できます。
session.setMaxInactiveInterval(300);
session.setAttribute("timeOutTimeInSeconds", 300);
session.setAttribute("showTimerTimeInSeconds", 30);
4.タイマーを表示するためのHTMLを以下に追加します。
注記:CSS に詳しい場合は、autologout-script テンプレート ページに移動できます。したがって、これを各ページに追加することを避けることができます。
ブートストラップを含めるか、カスタム CSS を追加します。
<span class="badge badge-primary" title="click to keep session alive" id="sessionTimeRemaining"
onclick="ajaxSessionRefresh()" style="display:none;">
<i class="badge badge-danger" id="sessionTimeRemainingBadge" style="float:left">30</i>
<small>Refresh</small>
<i class="glyphicon glyphicon-refresh"></i>
</span>
単純な自動ログアウトの実装については以上です。私の github リポジトリから実際のサンプルをダウンロードできます
単純なサーブレットの例を使用した自動ログアウト
spring-security Java 構成例を使用した自動ログアウト
spring-security XML 構成例を使用した自動ログアウト
ロジックの説明
ケース 1:ページ読み込み時
ここでのロジックは単純で、ページの読み込み時に間隔と等しいタイマーを maxInactiveInterval に設定します。タイムアウト後はログインページにリダイレクトされます。
ケース 2:AJAX 呼び出しを追跡する
ここで AJAX リクエストを考慮すると、jquery の .ajaxStart() または .ajaxComplete() コールバックを使用して、Ajax リクエストが起動された場合に間隔をリセットできます。
ケース 3:マルチタブ/ウィンドウアクティビティの追跡
タブ間通信は、各タブの状態を同期するために行われます。変更イベントで localStorage を使用しました。
制限事項/必要な改善
1.許可される最大セッションが 1 の場合、セッションが別のシステムから取得されると、AJAX リクエストは失敗します。ログインページにリダイレクトするように処理する必要があります。
2.サーバーとブラウザーの間で idleTime 値を正確に同期するには、ajaxComplete() の代わりに ajaxStart() を使用します。
要件
1.Jクエリ
現在の実装の代替案の比較
1. リフレッシュヘッダーの設定 http 応答で。 (AJAX リクエストでは機能しません)
response.setHeader("Refresh", "60; URL=login.jsp");
- メタリフレッシュタグの設定 HTMLで (AJAX リクエストでは機能しません)
<meta http-equiv="refresh" content="60; url=login.jsp">
- アクティビティチェッカーの構成繰り返しの AJAX リクエストによってセッションを維持します。アイドル時間を追跡し、タイムアウト後にログアウト要求を行います。
シンプルなロジックで優れたものであることは間違いありません。しかし、私は自分の観察を書き留めたいだけです。- パフォーマンスへの影響 セッションを維持し、50,000 人のアクティブ ユーザーを維持するために 1 分あたり 2 つのリクエストが行われた場合。1 分あたり 100,000 リクエスト。
- タブ間通信 2 つのタブが開いていて、1 つのタブがアクティビティを受信しているが、もう 1 つのタブがアクティビティを受信していない場合、他のタブにアクティビティが存在していても、そのタブはログアウト要求を発行してセッションを無効にします。(でも扱いは可能です)
- 強制ログアウトのアプローチ クライアントがサーバーよりも優位になってセッションを無効にすることです。
サーブレットセッションを使用している場合は、jsp / servletがjsp / servletが返されているかどうかを確認することができます(isnew()メソッドを使用する。もしそうなら、ユーザーのセッションが期限切れになり、関連メッセージを表示できます。
JSP内のJavaScriptユーティリティ機能を含み、サーバーを31分ごとにpingします。 上記のユーティリティ関数は、SetTimeout()JS関数を内部的に使用する必要があります。
setTimeout ( "checkServerSession()", /* intervalInMilliSeconds */ 31000);
.
に注意してください
checkserversession()
は、HTTP要求を発射する可能性がある通常のJS関数です。要求が成功した場合は、そうでなければユーザーへのプロンプトを表示します。