【发布时间】:2014-08-17 11:17:08
【问题描述】:
我有一个 Grails (2.3.6) 应用程序,需要用户登录才能访问该应用程序。一旦他们成功登录,他们就会被重定向到一个登录页面,该页面在右上角显示他们的用户名。我用以下 3 段代码很好地工作(或者我认为):
// myapp/grails-app/realms/myapp/MyAppRealm.groovy:
class MyAppRealm {
def onSuccessfulLogin(Principal principal) {
// Lots of code
// If I logged in successfully with a username of "user1", then principal.name will be "user1" here.
UserHolder.name = principal.name
// Lots more code
}
}
在上面的代码中,如果身份验证层确定他们成功登录,则执行onSuccessfulLogin() 方法。 principal.name 值是他们登录时使用的经过身份验证的用户名。如您所见,我将此值存储在 UserHolder POGO 中,如下所示:
class UserHolder {
static String name = null
static String getName() {
name
}
static void setName(String n) {
name = n
}
}
然后,在我的 GSP 文件中:
// myapp/grails-app/views/page.gsp
You are logged in as ${UserHolder?.name}.
刚刚收到一个测试员登录成功的报告,几分钟后按F5刷新屏幕,却发现他们的用户名属于另一个测试员!看了代码,原因很明显:UserHolder.name是静态变量;在任何给定时间点,只有 1 个实例会存在于服务器上。因此,如果user1 登录,他们将在 UI 中看到user1 作为他们的用户名。但是如果user2 然后登录,User.name 现在等于user2,如果user1 刷新他们的屏幕,他们会看到user2 作为他们的用户名。
所以我的下一个想法是尝试将principal.name 存储在像session.name = principal.name 这样的会话变量中:
// myapp/grails-app/realms/myapp/MyAppRealm.groovy:
class MyAppRealm {
def onSuccessfulLogin(Principal principal) {
// Lots of code
// If I logged in successfully with a username of "user1", then principal.name will be "user1" here.
session.name = principal.name
// Lots more code
}
}
...然后在 GSP 中引用它,例如 You are logged in as ${session.name}.。那里的问题是我无法从MyAppRealm.groovy 内部访问session,而且它不容易注入(除非有人能想到如何注入)。所以我问:我怎样才能在MyAppRealm中“记录”principal.name,然后从GSP中指定正确的用户名?
【问题讨论】: