Java 如何正确地使 JSP 会话无效?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3902688/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to properly invalidate JSP session?
提问by Morglor
So here is the problem. When a user logs out of my website, they can still hit the back button and continue using the site. To keep track of whether the user is logged in or not, I created a session attribute "isActive". The attribute is set to true when the user logs in, and is (redundantly) removed right before the session is invalidated at logout. Also on every page I check if the attribute is present.
所以问题来了。当用户退出我的网站时,他们仍然可以点击后退按钮并继续使用该网站。为了跟踪用户是否登录,我创建了一个会话属性“isActive”。该属性在用户登录时设置为 true,并在注销时会话失效之前(冗余地)删除。同样在每个页面上,我都会检查该属性是否存在。
I also specify that pages should not be cached in their head tags.
我还指定页面不应缓存在其 head 标签中。
Despite this users are still able to hit back on the browser, and continue to use the site as if they never logged off.
尽管如此,用户仍然可以回击浏览器,并继续使用该网站,就好像他们从未注销过一样。
Any idea on how to fix this?
关于如何解决这个问题的任何想法?
Here is the code:
这是代码:
Login Servlet:
登录小服务程序:
...
session.setAttribute("isActive", true);
//Redirect to home page.
Check Logged In JSP:
检查已登录 JSP:
<c:if test='${empty sessionScope.isActive || sessionScope.isActive != true}'>
<c:redirect url="/index.jsp?message=Session Timed Out."/>
</c:if>
Logout Servlet:
注销小服务程序:
request.getSession().removeAttribute("isActive");
request.getSession().invalidate();
response.sendRedirect("index.jsp");
Inside Head Tag:
内头标签:
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="Sat, 01 Dec 2001 00:00:00 GMT">
Thanks
谢谢
采纳答案by BalusC
The meta tags are not sufficient. You need to add them as fullworthy response headers. The webbrowser relies on them. A Filter
is helpful in this. Also, the Cache-Control
header is incomplete (won't work as expected in Firefox, among others).
元标记是不够的。您需要将它们添加为完全值得的响应标头。网络浏览器依赖于它们。AFilter
在这方面很有帮助。此外,Cache-Control
标头不完整(在 Firefox 等中无法按预期工作)。
Implement this in the doFilter()
method of a Filter
which is mapped on an url-pattern
of for example *.jsp
(if you want to cover all JSP pages).
例如,在映射到of的doFilter()
方法中实现这一点(如果您想覆盖所有 JSP 页面)。Filter
url-pattern
*.jsp
HttpServletResponse res = (HttpServletResponse) response;
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
res.setHeader("Pragma", "no-cache"); // HTTP 1.0.
res.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(request, response);
This way the webbrowser will be forced to fire a real request on the server rather than displaying the page from the browser cache. Also, you should rather be using a Filter
to check the presence of the logged-in user, not JSP/JSTL.
这样 webbrowser 将被迫在服务器上触发一个真正的请求,而不是从浏览器缓存中显示页面。此外,您应该使用 aFilter
来检查登录用户的存在,而不是 JSP/JSTL。
Related questions:
相关问题:
回答by Colin Hebert
You shouldn't check if the session is still active on your destination page, it's better to check it with a Filter
.
您不应该检查目标页面上的会话是否仍处于活动状态,最好使用Filter
.
If in the filter, request.getSession().getAttribute("isActive")
returns something, then the user is still logged, and you simply chain; else you redirect on the login page.
如果在过滤器中request.getSession().getAttribute("isActive")
返回某些内容,则用户仍处于登录状态,您只需链接即可;否则你在登录页面上重定向。
For example :
例如 :
public class ActiveFilter implements Filter {
public void init(FilterConfig filterConfig)
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if (req.getSession().getAttribute("isActive") == null){
res.sendRedirect("/index.jsp");
}else{
chain.doFilter(request, response);
}
}
}
Resources :
资源 :
回答by Peter L
All my JSP's have no-cache headers (via @include directives). I have a logout.jspin the root of the app with the following lines:
我所有的 JSP 都没有缓存头(通过 @include 指令)。我在应用程序的根目录中有一个logout.jsp,其中包含以下几行:
HttpSession sessIfAny = request.getSession(false);
if (sessIfAny != null) sessIfAny.invalidate();
This prevents creating unnecessary sessions.
这可以防止创建不必要的会话。
The web.xml needs to exempt logout.jsp from authentication:
web.xml 需要免除 logout.jsp 的身份验证:
<!-- Resources excepted from authentication -->
<security-constraint>
<web-resource-collection>
<web-resource-name>excepted</web-resource-name>
<url-pattern>/logout.jsp</url-pattern>
<url-pattern>/favicon.ico</url-pattern>
<!-- ... other resources -->
</web-resource-collection>
<!-- no auth-constraint -->
</security-constraint>
This prevents a login page being shown to do a logout on an expired session.
这可以防止显示登录页面以在过期会话上注销。