English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

javawebユーザーのログアウト後にブラウザを戻ってページをリフレッシュすると再びログインする問題の解決方法

最近、書籍購入サイトを書いており、ログアウト機能をテスト中にブラウザを戻るボタンをクリックしてリフレッシュすると、既にログアウトしたユーザーが再びログインしたことに気づきました。 

長い時間をかけて、オンラインで多くの方法を探しましたが、オンラインで提供されている多くの方法は、ログアウト後にユーザーがブラウザの戻るボタンをクリックを禁止するためにjsを使用しています。 

この方法は実用的ですが、実際にバックエンドで問題を解決しているわけではありません。防君子不防小人のような感じがあります。 

以下に自分が実装した方法を記録します。 

原理: 

ログアウト後にブラウザを戻るボタンをクリックしてリフレッシュするのは、ブラウザが元のformフォームの情報を再送信するのと同じです。 

ログアウトとは、元のsessionを削除することです。

// ログアウト
 private void logout(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  HttpSession session = request.getSession();
  request.setAttribute("sessionId", session.getId());
  session.removeAttribute("user");
  session.invalidate();
  response.sendRedirect(request.getContextPath()) + "/index.jsp");
 } 

ログアウト後にリダイレクトされるjspページでは、sessionは元のsessionとは異なります(jspページのsessionはデフォルトで有効になっています)。 

つまり、ログアウト後にブラウザを戻るボタンをクリックしてリフレッシュするsessionは新しいsessionであり、この視点から解決策を考えてみましょう。 

元のsessionにデータを入れて、初めてログインするとそのデータが取得できるが、ログアウトした後、元のsessionはなくなります。ブラウザを戻るボタンをクリックしてリフレッシュすると、新しいsessionにはデータが入れていないため、取得した値はnullです。 

元のセッション内のデータと新しいセッションの値を照合し、一方が値を持って一方がnullであると、照合は失敗します。この場合、ユーザーにフレンドリーなアラートを表示し、ユーザーに再ログインを促します。 

では、ログアウト後(元のセッションが消えた後)元のセッション内のデータはどのように保存しますか?フォームに隠されたフィールドを追加し、元のセッション内のデータをその隠されたフィールドに置きます。これにより、ログアウト後にブラウザを戻る/リフレッシュすると、ブラウザが自動的に元のセッション内のデータを再提出します(実際には、手動で保存する場合はservletContextアプリケーションコンテキスト内に配置する必要がありますが、試していないです)

フォームの重複送信を解決する方法に似ていますが、ここでは元のセッション内のデータを削除することはできません。なぜなら、ログアウト前後では同じセッションではないからです 

具体的には、login.jsp内で以下の通りです:

<%
String token=new Random().nextLong()+"";
session.setAttribute("token", token);
%>
<form action="${pageContext.request.contextPath}/servlet/ClientServlet?operation=login" method="post">
<table style="width: 50%;">
<tr>
<td align="right">名前:</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td align="right">パスワード:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<tr>
<td></td>
<td><input type="submit" value="ログイン"></td>
</tr>
</table>
<input type="hidden" name="token" value="${sessionScope.token}">
</form> 

サーブレットでユーザーにフレンドリーなアラートを表示し、ログインページにリダイレクトします 

  HttpSession session = request.getSession();
  //ログアウト後にブラウザを戻る/リフレッシュしてから再度ログインする問題を解決します
  //隠された入力フィールドを提供し、バックエンドが隠されたフィールドの値を取得します
  //ログアウト後にブラウザをリフレッシュすると新しいセッションが生成され、そのためセッショントークンがnullになります
  //これでhiddenToken.equals(sessionToken)は常にfalseです
  String sessionToken = (String) session.getAttribute("token");
  String hiddenToken = request.getParameter("token");
  if (!hiddenToken.equals(sessionToken)) {
   request.setAttribute("message", "您已注销,请重新登录",2秒後转向ログインページ<meta http-equiv='Refresh' content=2;url="
       + request.getContextPath() + "/client/login.jsp>");
   request.getRequestDispatcher("/client/message.jsp").forward(
     request, response);
   return;
  } 

テスト: 

ログイン

 

アカウントを削除後、ブラウザに戻ってリフレッシュすると、ブラウザはデータを再送信するかどうかの確認を表示します。

 

再送信をクリックしてください

 

これでアカウントを削除後、ブラウザに戻ってリフレッシュし、再びログインする問題が解決しました。

これで本文の全てが終わりました。皆様の学習に役立てば幸いです。また、呐喊チュートリアルを多くのサポートをお願いします。

声明:本文の内容はインターネットから提供されています。著作権は原著者に帰属します。インターネットユーザーが自発的に貢献し、アップロードしたものであり、本サイトは所有権を有しません。また、人工的な編集は行われていません。著作権侵害を疑う内容があれば、メールを送信してください:notice#oldtoolbag.com(メールを送信する際には、#を@に置き換えてください。告発を行い、関連する証拠を提供してください。一旦確認がとれましたら、本サイトは即座に侵害を疑われるコンテンツを削除します。)

おすすめ