2011-04-12 78 views
3

当用户试图访问管理控制器中的页面(通常是CRUD内容)时,他将被重定向到登录页面。而且,如果凭证是正确的并且他确实是管理员,他将开始重定向到他希望在前一个请求中访问的页面。Flash范围内的变量不会在Google Chrome中保持活跃状态​​

每当有人试图访问他被重定向到以下控制器被禁止的网页:

public static void login(String returnUrl) throws Throwable { 
    Http.Cookie remember = request.cookies.get("rememberme"); 
    flash.put("url",returnUrl); 
    if (remember != null && 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()是一个在参数或flash范围内接收returnUrl的方法。

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。这是一个已知的问题,还是我在做一些非常错误的事情?

没有特别要求或者任何。从不可访问页面(localhost:9000/admin)重定向时的url为http://localhost:9000/account?returnUrl=%2Fadmin。所以没有错......

因此错误必须在于验证控制器,似乎无法将参数传递给redirectToOriginalURL方法。但是,只能在Google Chrome中使用。

对此提出建议?

回答

2

我得到它的工作是这样的:

确保checkAccess方法调用登录方法与当前的URL:

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

然后在login.html的视图中添加的隐藏字段,它是帕拉姆你已经传递到登录方法:

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

或者添加RETURNURL PARAM直接form.action:

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

就是这样。而且你不需要Flash范围。

+1

这工作就像一个魅力!谢谢! 有没有一种方法从控制器收集查询字符串中的参数?因为如果你必须在你的视图中放置一个隐藏的字段,每次你想重定向...这很难保持:)感谢您的帮助! – Jasper 2011-04-13 09:00:47

+1

是的,使用这个:#{form @authenticate()。添加(“returnUrl”,params.returnUrl)} – wassertim 2011-04-13 12:13:38

+0

谢谢蒂姆!非常感激 – Jasper 2011-04-14 08:45:09

1

我注意到,在登录这行代码:

redirectToOriginalURL(); 

,调用不带参数的方法,但是你展示redirectToOriginalURL有一个参数字符串。难道这是问题的一部分吗?

+1

这是来自复制粘贴的一个人工制品......当然,参数中应该有returnUrl。感谢您指出了这一点! – Jasper 2011-04-12 13:30:27