переменные в области flash не сохраняются в Google Chrome

#java #google-chrome #playframework

#java #google-chrome #playframework

Вопрос:

Когда пользователь пытается получить доступ к странице в контроллерах администрирования (в основном, к CRUD-материалам), он перенаправляется на страницу входа в систему. И, если учетные данные верны, и он действительно администратор, он начинает перенаправляться на страницу, к которой он хотел получить доступ в предыдущем запросе.

Всякий раз, когда кто-то пытается получить доступ к запрещенной странице, он перенаправляется на следующий контроллер:

     public static void login(String returnUrl) throws Throwable {
    Http.Cookie remember = request.cookies.get("rememberme");
    flash.put("url",returnUrl);
    if (remember != null amp;amp; remember.value.indexOf("-") > 0) {
        String sign = remember.value.substring(0, remember.value.indexOf("-"));
        String username = remember.value.substring(remember.value.indexOf("-")   1);
        if (Crypto.sign(username).equals(sign)) {
            session.put("username", username);
            redirectToOriginalURL(returnUrl);
        }
    }
    flash.keep();
    render();
}
  

Который выполняет метод authenticte (…):

 public static void authenticate(@Required String username, String password, boolean remember, String returnUrl) throws Throwable {
    // Check tokens
    Boolean allowed = false;
    // This is the official method name
    allowed = (Boolean) Security.invoke("authenticate", username, password);
    if (validation.hasErrors() || !allowed) {
        flash.keep("url");
        flash.error("secure.error");
        params.flash();
        login(returnUrl);
    }
    // Mark user as connected
    session.put("username", username);
    // Remember if needed
    if (remember) {
        response.setCookie("rememberme", Crypto.sign(username)   "-"   username, "30d");
    }
    // Redirect to the original URL (or /)
    flash.keep("url");
    redirectToOriginalURL(returnUrl);
}
  

Обратите внимание на String returnUrl в списке параметров. Этот контроллер всегда вызывается в представлении со response.url значением.

redirectToOriginalURL() — это метод, который получает returnUrl в параметре или в области flash.

 static void redirectToOriginalURL(String returnUrl) throws Throwable {
    if(returnUrl==null) returnUrl = flash.get("url");
    if (returnUrl == null) {
        returnUrl = "/";
    }
    redirect(returnUrl);
}
  

Это отлично работает в Firefox и Internet Explorer. Но когда я пытаюсь выполнить это в Google Chrome, returnUrl является null . Это известная проблема, или я делаю что-то ужасно неправильное?

Нет никаких специальных запросов или чего-либо еще. URL-адрес при перенаправлении с недоступной страницы ( localhost:9000/admin ) является http://localhost:9000/account?returnUrl=/admin . Так что ничего плохого там нет…

Следовательно, ошибка должна быть связана с контроллером аутентификации, который, похоже, не может передать аргументы методу redirectToOriginalURL. Но, опять же, только в Google Chrome.

Предложения?

Ответ №1:

У меня это работает таким образом:

Убедитесь, что метод checkAccess вызывает метод login с текущим URL:

 static void checkAccess() throws Throwable {
    // Authent
    if (!session.contains("username")) {            
        login(request.method.equals("GET") ? request.url : "/");
    }
}
  

Затем в login.html просмотр добавьте скрытое поле, которое является параметром, который вы уже передали методу login:

 #{form @authenticate()}
<input type="hidden" name="returnUrl" value="${params.returnUrl}">
...
#{/form}
  

Или добавьте параметр returnUrl непосредственно в form.action:

 #{form @authenticate().add("returnUrl", params.returnUrl)}
  

Вот и все. И вам не нужна область flash.

Комментарии:

1. Это работает как шарм! Спасибо! Есть ли способ сбора параметров в строке запроса с контроллера? Потому что, если вам нужно поместить скрытое поле в свой view, каждый раз, когда вы хотите перенаправить… Это сложно поддерживать 🙂 Спасибо за помощь!

2. Да, используйте это: #{form @authenticate().add(«returnUrl», params.returnUrl)}

Ответ №2:

Я заметил эту строку кода в login:

  redirectToOriginalURL();
  

Это вызывает метод без аргументов, но показанный вами redirectToOriginalURL содержит строку параметров. Может быть, это часть проблемы?

Комментарии:

1. Это артефакт при копировании-вставке… в параметре, конечно, должен быть returnUrl. Спасибо, что указали на это!