6

ログイン(覚えておいてください)アプリケーションを実装しようとしていますが、Cookieの管理に問題があります。登録(新規メンバーの場合)またはログイン(すでに登録されているメンバーの場合)を実行している場合、サーバーで実行しています。

Cookie returnVisitorCookie = new Cookie("repeatVisitor", "yes");
returnVisitorCookie.setMaxAge(60*60*24*365); // 1 year
response.addCookie(returnVisitorCookie);

ここで、ブラウザから取得する応答。例:visitor.login(response)。

SIGNOUTを実行しているときは、Cookieを削除しています。しかし、本来あるべきCookieがもっとあるようです。つまり、2人のメンバーを登録してサインアウトした場合でも、名前が「repeatVisitor」で値が「yes」のCookieが残っています。

たぶん私はクッキーを別の応答に入れているからです。

誰でも私が間違っていることをidaeに教えてくれますが、これをどのように実装すればよいですか?ありがとうございました

4

2 に答える 2

2

私は時々、例を見て学ぶことや理解するための最良の方法を見つけます. 動作中の Web サイトに使用するコードを次に示します。

@WebServlet(name = "Login", urlPatterns = {"/authorization/Login"})
public class Login extends HttpServlet {

    /**
     * Processes requests for both HTTP
     * <code>GET</code> and
     * <code>POST</code> methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        PrintWriter out = response.getWriter();
        try {
            System.out.println("Reached login");
            if (!Authorization.isLoggedIn(request)) {
                String login = request.getParameter("login");
                String password = request.getParameter("password");
                boolean remember = Boolean.parseBoolean(request.getParameter("remember"));

                System.out.println("Reached login "+login+", "+password+","+remember);
                if (!Authorization.validateLogin(login, password)) {
                    Logger.getLogger(Login.class.getName()).log(Level.INFO,
                            "Failed login (invalid password) from {0} for {1}",
                            new String[]{request.getRemoteAddr(), login});
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid username or password!");
                    return;
                }
                //So far so good... Get the user object from the database (unique login names)
                DB_User user = DB_User.get(login);
                if (!user.getActive()) {
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Your account is no longer active!");
                    return;
                }
                String sessionID = Authorization.createNewSession(user, request.getRemoteAddr(), remember);
                Cookie sessionCookie = new Cookie("my_application.session_id", sessionID);
                sessionCookie.setDomain(request.getServerName());
                sessionCookie.setPath(request.getContextPath());
                if (remember) {
                    sessionCookie.setMaxAge(ServerConfig.getLoginSessionTimeout());
                }

                response.addCookie(sessionCookie);
            }
            response.sendRedirect("/app/myAccount.jsp");
        } catch (Throwable ex) {
            Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
            ServletUtils.handleException(ex, response);
        } finally {
            out.flush();
            out.close();
        }
    }

    // +HttpSerlet default methods here. (doGet, doPost, getServletInfo)
}

ログアウト サーブレットの例:

@WebServlet(name = "Logout", urlPatterns = {"/authorization/Logout"})
public class Logout extends HttpServlet {

    /**
     * Processes requests for both HTTP
     * <code>GET</code> and
     * <code>POST</code> methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            String sessionID = ServletUtils.getCookieValue(request.getCookies(),"my_application.session_id");

            if (sessionID != null) {
                SQLManager sql = ServerConfig.getSql();
                sql.deleteFromTable("login_session", "session_id = " + SQLString.toSql(sessionID));

                Cookie sessionCookie = new Cookie("my_application.session_id", null);
                sessionCookie.setDomain(ServletUtils.getCookieDomain(request));
                sessionCookie.setPath("/you_app_name");
                sessionCookie.setMaxAge(0);
                response.addCookie(sessionCookie);
            }
            response.sendRedirect("/security/login.jsp");

        } catch (Throwable ex) {
            Logger.getLogger(Logout.class.getName()).log(Level.SEVERE, null, ex);
            ServletUtils.handleException(ex, response);
        } finally {
            out.close();
        }
    }
}

お気づきのように、作成したヘルパー クラスがいくつかありますが、それでもコンセプトはそこにあります。お役に立てれば

于 2014-03-10T22:17:35.567 に答える
0

少なくとも 1 年間は後続のリクエストで Cookieを保持し続けますrepeatVisitor。クライアントのブラウザに「Cookie を 1 年間保持する」ように指示しました。後続のリクエスト ヘッダーから Cookie を削除しても、ブラウザが単純に再追加することはありません。

覚えておいてくださいを正常に実装するには、次のことが必要です。

  1. 「repeat user : yes」というフラグだけでなく、安全なトークンを使用してください。Java の UUID クラスのようなものを使用して一意のトークンを生成し、訪問者を安全に一意に識別します。

  2. ユーザーごとに生成したセキュア トークンを積極的に管理します。つまり、生成したトークンを永続的なストレージに保存し、このストアに対して繰り返し要求をチェックします。トークンの有効期限などを管理するのは、このストア内です。したがって、永続ストアでは、トークンに非アクティブまたは期限切れのフラグを立てることができます

別の方法として、remember-me を一定の期間に設定し、HttpServletRequestオブジェクトに Cookie の有効期限を設定する方法がより簡単です。つまり、チェック ボックスにメッセージが表示remember me for 2 weeksされ、Cookie の有効期限が 2 週間に設定されます。同じ Cookie トークンの後続の表現は、ストレスなく自動的に管理されます。

于 2012-10-29T17:44:17.973 に答える