登录后重定向回页面

2022-09-02 23:59:01

我正在做一个简单的论坛,其中包含一系列论坛,每个论坛代表一个主页,主题,后期编辑,登录和用户列表页面。在其中一些页面上,当用户未登录时,会出现一个链接。Servlets

我想实现的是登录后触发重定向(在 RequestDispatcher 上使用 forward()),以便浏览器返回到用户在单击登录链接之前所在的页面。为了做到这一点,我看到了两种解决方案。

第一种解决方案是使用带有登录按钮的HTML和一个不可见的字段,该字段将包含信息,这些信息将指示要重定向的页面作为.这是可行的,但我想尝试别的东西。FormParameter

第二种解决方案是向 添加一个,以某种方式表示第一个“页面”。这可以包含一个字符串,但这与第一种方法没有什么不同。另一个转折是添加对 HttpServlet 的引用,并使用 instanceof 或静态 String 变量,它可以用来以某种方式标识 Servlet。但是,这需要为所有 .AttributesessionServlets

也许你可以看到另一个简单的解决方案,这将形成一个很好的妥协 ?或者,也许上述解决方案之一是完全可以接受的?


答案 1

我更喜欢第一种解决方案,而不是第二种解决方案。这是请求范围的信息,实际上不属于会话,它只会在同一会话中打开多个窗口/选项卡时导致“wtf?”体验。

在指向登录页面的链接上,只需将当前 URL 作为请求参数传递:

<a href="/login?from=${pageContext.request.requestURI}">Login</a>

或者,如果它是登录页面的POST表单:

<input type="hidden" name="from" value="${pageContext.request.requestURI}">

在登录表单中,将其作为隐藏变量传输到下一个请求:

<input type="hidden" name="from" value="${param.from}">

在登录 servlet 中,使用它:

User user = userDAO.find(username, password);
if (user != null) {
    request.getSession().setAttribute("user", user);
    response.sendRedirect(request.getParameter("from"));
} else {
    // Show error.
}

相当简单,不是吗?:)

有些人可能会建议在登录表单中而不是在登录前的链接/按钮中使用,但我不会这样做,因为这是由客户端控制的,并不总是返回可靠的信息。一些客户已经禁用了它,或者正在使用某些软件来欺骗它,使其具有无效的值,例如大多数(咳嗽)赛门铁克产品。request.getHeader("referer")request.getRequestURI()


答案 2

您建议的第一种方法是最好的方法。具有隐藏字段,并在登录后重定向到该URI。value=request.getRequestURI()

使用将不起作用,因为IE(至少其某些版本)不会设置标头。refererreferer

如果用户打开多个选项卡,则在会话中存储参数会导致奇怪的行为。

编辑:为了更好地说明问题:

some resource -> (requests protected resource) -> (gets forwarded to the login page) -> (should be redirected to the original resource)

大多数答案假设单击“登录”链接/按钮,然后打开登录页面。这只是故事的一个方面。在这种情况下,可以将原始资源 URL 添加为参数,并将其放置在登录表单中(在隐藏字段中)。

但是,如果从受保护的资源转发到登录页面,则隐藏字段应包含即时请求 URL。

当然,这不是问题所在,但最终将作为一种情况出现,也应该加以考虑。