Grails:运行ajax请求时用户注销
Posted
技术标签:
【中文标题】Grails:运行ajax请求时用户注销【英文标题】:Grails: User logs out while ajax request is running 【发布时间】:2014-07-31 00:46:31 【问题描述】:有一个带有 Spring Security Core 插件 (v.2.0-RC2) 的 Grails (v.2.3.2) Web 应用程序。
我偶然发现了一个用户在后台运行 ajax 请求时注销的问题。
场景如下:
-
用户请求网页
页面准备就绪后,我会触发 ajax 请求
在服务器端仍在处理 ajax 请求时用户注销
服务器端自然严重依赖当前用户,第三步app就崩溃了,因为当前用户突然消失,springSecurityService
表示用户未登录。
这是我用来在UserService
中获取当前用户的代码。
public User getLoggedInUser()
if (!springSecurityService.isLoggedIn())
return null
User user = User.get(springSecurityService.getPrincipal().id)
user
这会在用户注销之前正常返回当前用户,从而导致问题。
我想出了使UserService
有状态并将当前用户存储在单独字段中的想法。
static scope = 'request' // create a new instance for every request
private Long currentUserId = null
public User getLoggedInUser()
if (!currentUserId)
if (!springSecurityService.isLoggedIn())
return null
// Store the ID of the current user in the instance variable.
currentUserId = springSecurityService.getPrincipal().id
// Fetch and return the user.
return User.get(currentUserId)
此外,我创建了一个新的Spring
bean,它为我的UserService
定义了一个代理对象。
userServiceProxy(ScopedProxyFactoryBean)
targetBeanName = 'userService'
proxyTargetClass = true
现在,这在大多数情况下都非常有效,但在没有 Web 请求存在时会失败。特别是在BootStrap.groovy
,我使用我的应用程序的其他服务。
这是我收到的错误消息:
初始化应用程序时出错:创建名为“scopedTarget.userServiceProxy”的 bean 时出错:范围“请求”对当前线程无效;如果您打算从单例中引用它,请考虑为该 bean 定义一个作用域代理;嵌套异常是 java.lang.IllegalStateException:未找到线程绑定请求:您是指实际 Web 请求之外的请求属性,还是在原始接收线程之外处理请求?如果您实际上是在 Web 请求中操作并且仍然收到此消息,则您的代码可能在 DispatcherServlet/DispatcherPortlet 之外运行:在这种情况下,请使用 RequestContextListener 或 RequestContextFilter 来公开当前请求。
关于如何解决此问题的任何建议?
【问题讨论】:
【参考方案1】:经过一番调查和大量脏话,终于找到了解决方案。
这是我在BootStrap.groovy
中用来模拟正在进行的网络请求的代码。
class BootStrap
def init = ServletContext servletContext ->
// Mock request and response.
HttpServletRequest request = new MockHttpServletRequest(servletContext)
HttpServletResponse response = new MockHttpServletResponse()
// Now store them in the current thread.
GrailsWebRequest grailsRequest = new GrailsWebRequest(request, response, servletContext)
WebUtils.storeGrailsWebRequest(grailsRequest)
/**
* Perform whatever you need to do that requires an active web request.
*/
【讨论】:
以上是关于Grails:运行ajax请求时用户注销的主要内容,如果未能解决你的问题,请参考以下文章
Ajax PUT 请求导致 Rails 应用程序注销。为啥?
每当进行 AJAX POST 时,Laravel 4 应用程序都会将用户注销