会话或cookie混淆

前端之家收集整理的这篇文章主要介绍了会话或cookie混淆前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在一些网站上看到用户登录他们的帐户,然后关闭了浏览器。

关闭并重新打开后,浏览器和帐户仍然登录

但有些网站,不能这样做。

我很困惑,认为它是会话或cookie?

如果我想要我的网站登录,我必须设置session.setMaxInactiveInterval()或cookie.setMaxAge()?

@R_502_323@

你的问题是关于会话跟踪。

[PART 1]:SESSION OBJECT

HTTP请求被单独处理,所以为了保持每个请求之间的信息(例如,关于用户的信息),必须在服务器端创建会话对象。

一些网站根本不需要一个会话。用户不能修改任何内容的网站将不必管理会话(例如,在线简历)。您不会在这样的网站上需要任何Cookie或会话。

创建会话:

在servlet中,使用HttpServletRequest对象中的request.getSession(true)方法创建一个新的HttpSession对象。请注意,如果您使用request.getSession(false),如果会话尚未创建,则返回null。 Look at this answer for more details

设置/获取属性

会话的目的是在每个请求之间保留服务器端的信息。例如,保留用户名

  1. session.setAttribute("name","MAGLEFF");
  2. // Cast
  3. String name = (String) session.getAttribute("name");

破坏会话:

如果保持不活动的时间太长,会话将自动销毁。 Look at this answer for more details.但您可以手动强制会话被破坏,例如在注销动作的情况下:

  1. HttpSession session = request.getSession(true);
  2. session.invalidate();

[第二部分]:那么加入黑暗的一面,我们有COOKIES?

这里是饼干。

JSESSIONID:

每次使用request.getSession()创建会话时,都会在用户计算机上创建一个JSESSIONID cookie。为什么?因为在服务器端创建的每个会话都有一个ID。您无法访问其他用户的会话,除非您没有正确的ID。此ID保存在JSESSIONID cookie中,并允许用户查找他的信息。 Look at this answer for more details

什么时候删除JSESSIONID?

JSESSIONID没有到期日期:它是一个会话cookie。作为所有会话cookie,当浏览器关闭时,它将被删除。如果您使用基本的JSESSIONID机制,则在关闭并重新打开浏览器后,会话将无法访问,因为JSESSIONID cookie已被删除

请注意,会话无法由客户端访问,但仍在服务器端运行。设置MaxInactiveInterval允许服务器在不活动时间长时间内自动使会话无效。

JSESSIONID的恶意破坏

只是为了好玩,有一天我发现这个代码在一个项目上。用于通过使用javascript删除JSESSIONID cookie来使会话无效:

  1. <SCRIPT language="JavaScript" type="text/javascript">
  2.  
  3. function delete_cookie( check_name ) {
  4. // first we'll split this cookie up into name/value pairs
  5. // note: document.cookie only returns name=value,not the other components
  6. var a_all_cookies = document.cookie.split( ';' );
  7. var a_temp_cookie = '';
  8. var cookie_name = '';
  9. var cookie_value = '';
  10. var b_cookie_found = false; // set boolean t/f default f
  11. // var check_name = 'JSESSIONID';
  12. var path = null;
  13.  
  14. for ( i = 0; i < a_all_cookies.length; i++ )
  15. {
  16. // now we'll split apart each name=value pair
  17. a_temp_cookie = a_all_cookies[i].split( '=' );
  18. // and trim left/right whitespace while we're at it
  19. cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g,'');
  20. // alert (cookie_name);
  21.  
  22. // if the extracted name matches passed check_name
  23. if ( cookie_name.indexOf(check_name) > -1 )
  24. {
  25. b_cookie_found = true;
  26. // we need to handle case where cookie has no value but exists (no = sign,that is):
  27. if ( a_temp_cookie.length > 1 )
  28. {
  29. cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g,'') );
  30. document.cookie = cookie_name + "=" + cookie_value +
  31. ";path=/" +
  32. ";expires=Thu,01-Jan-1970 00:00:01 GMT";
  33. // alert("cookie deleted " + cookie_name);
  34. }
  35. }
  36. a_temp_cookie = null;
  37. cookie_name = '';
  38. }
  39. return true;
  40. }
  41. // DESTROY
  42. delete_cookie("JSESSIONID");
  43.  
  44. </SCRIPT>

使用JavaScript,JSESSIONID可以被读取,修改,丢失或被劫持。

[第3部分]:在关闭您的浏览器后,请保留会议

After closed and re-opened the browser and their accounts are still
signed in.
But some websites,cannot do like that.
I’m confused that it’s considered session or cookie??

这是cookie。

我们看到当JSESSIONID会话cookie已被Web浏览器删除时,服务器端的会话对象将丢失。没有正确的ID没有办法再次访问它。

If I want my website to be signed in like that,do I have to set
session.setMaxInactiveInterval() or cookie.setMaxAge()?

我们还看到session.setMaxInactiveInterval()是为了防止无限期地运行丢失的会话。 JSESSIONID cookie cookie.setMaxAge()也不会让我们在任何地方。

使用持久性cookie与会话ID:

阅读以下主题后,我来到了这个解决方案:

> How to implement “Stay Logged In” when user login in to the web application由BalusC
> http://simple.souther.us/not-so-simple.html by Ben Souther; ben@souther.us

主要思想是在Map中注册用户的会话,放入servlet上下文中。每次创建会话时,都将其添加到Map的JSESSIONID值为key;还创建一个持久性cookie来记住JSESSIONID值,以便在JSESSIONID cookie被破坏后找到会话。

关闭Web浏览器时,JSESSIONID将被销毁。但是所有HttpSession对象的地址都保存在服务器端的Map中,您可以使用保存在持久性cookie中的值访问正确的会话。

首先,在web.xml部署描述符中添加两个监听器。

  1. <listener>
  2. <listener-class>
  3. fr.hbonjour.strutsapp.listeners.CustomServletContextListener
  4. </listener-class>
  5. </listener>
  6.  
  7. <listener>
  8. <listener-class>
  9. fr.hbonjour.strutsapp.listeners.CustomHttpSessionListener
  10. </listener-class>
  11. </listener>

CustomServletContextListener在上下文初始化时创建一个映射。该地图将注册用户在此应用程序中创建的所有会话。

  1. /**
  2. * Instanciates a HashMap for holding references to session objects,and
  3. * binds it to context scope.
  4. * Also instanciates the mock database (UserDB) and binds it to
  5. * context scope.
  6. * @author Ben Souther; ben@souther.us
  7. * @since Sun May 8 18:57:10 EDT 2005
  8. */
  9. public class CustomServletContextListener implements ServletContextListener{
  10.  
  11. public void contextInitialized(ServletContextEvent event){
  12. ServletContext context = event.getServletContext();
  13.  
  14. //
  15. // instanciate a map to store references to all the active
  16. // sessions and bind it to context scope.
  17. //
  18. HashMap activeUsers = new HashMap();
  19. context.setAttribute("activeUsers",activeUsers);
  20. }
  21.  
  22. /**
  23. * Needed for the ServletContextListener interface.
  24. */
  25. public void contextDestroyed(ServletContextEvent event){
  26. // To overcome the problem with losing the session references
  27. // during server restarts,put code here to serialize the
  28. // activeUsers HashMap. Then put code in the contextInitialized
  29. // method that reads and reloads it if it exists...
  30. }
  31. }

CustomHttpSessionListener在会话创建时将会将其置于activeUsers映射中。

  1. /**
  2. * Listens for session events and adds or removes references to
  3. * to the context scoped HashMap accordingly.
  4. * @author Ben Souther; ben@souther.us
  5. * @since Sun May 8 18:57:10 EDT 2005
  6. */
  7. public class CustomHttpSessionListener implements HttpSessionListener{
  8.  
  9. public void init(ServletConfig config){
  10. }
  11.  
  12. /**
  13. * Adds sessions to the context scoped HashMap when they begin.
  14. */
  15. public void sessionCreated(HttpSessionEvent event){
  16. HttpSession session = event.getSession();
  17. ServletContext context = session.getServletContext();
  18. HashMap<String,HttpSession> activeUsers = (HashMap<String,HttpSession>) context.getAttribute("activeUsers");
  19.  
  20. activeUsers.put(session.getId(),session);
  21. context.setAttribute("activeUsers",activeUsers);
  22. }
  23.  
  24. /**
  25. * Removes sessions from the context scoped HashMap when they expire
  26. * or are invalidated.
  27. */
  28. public void sessionDestroyed(HttpSessionEvent event){
  29. HttpSession session = event.getSession();
  30. ServletContext context = session.getServletContext();
  31. HashMap<String,HttpSession> activeUsers = (HashMap<String,HttpSession>)context.getAttribute("activeUsers");
  32. activeUsers.remove(session.getId());
  33. }
  34.  
  35. }

使用基本形式通过名称/密码测试用户身份验证。这个login.jsp表单仅用于测试。

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <head>
  4. <Meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  5. <title><bean:message key="formulaire1Title" /></title>
  6. </head>
  7. <body>
  8. <form action="login.go" method="get">
  9. <input type="text" name="username" />
  10. <input type="password" name="password" />
  11. <input type="submit" />
  12. </form>
  13. </body>
  14. </html>

我们走了当用户不在会话中时,这个java servlet正在转发到登录页面,而在他的时候转到另一个页面。它只是用于测试持续会话!

  1. public class Servlet2 extends AbstractServlet {
  2.  
  3. @Override
  4. protected void doGet(HttpServletRequest pRequest,HttpServletResponse pResponse) throws IOException,ServletException {
  5. String username = (String) pRequest.getParameter("username");
  6. String password = (String) pRequest.getParameter("password");
  7. // Session Object
  8. HttpSession l_session = null;
  9.  
  10. String l_sessionCookieId = getCookieValue(pRequest,"JSESSIONID");
  11. String l_persistentCookieId = getCookieValue(pRequest,"MY_SESSION_COOKIE");
  12.  
  13. // If a session cookie has been created
  14. if (l_sessionCookieId != null)
  15. {
  16. // If there isn't already a persistent session cookie
  17. if (l_persistentCookieId == null)
  18. {
  19. addCookie(pResponse,"MY_SESSION_COOKIE",l_sessionCookieId,1800);
  20. }
  21. }
  22. // If a persistent session cookie has been created
  23. if (l_persistentCookieId != null)
  24. {
  25. HashMap<String,HttpSession> l_activeUsers = (HashMap<String,HttpSession>) pRequest.getServletContext().getAttribute("activeUsers");
  26. // Get the existing session
  27. l_session = l_activeUsers.get(l_persistentCookieId);
  28. }
  29. // Otherwise a session has not been created
  30. if (l_session == null)
  31. {
  32. // Create a new session
  33. l_session = pRequest.getSession();
  34. }
  35.  
  36. //If the user info is in session,move forward to another page
  37. String forward = "/pages/displayUserInfo.jsp";
  38.  
  39. //Get the user
  40. User user = (User) l_session.getAttribute("user");
  41.  
  42. //If there's no user
  43. if (user == null)
  44. {
  45. // Put the user in session
  46. if (username != null && password != null)
  47. {
  48. l_session.setAttribute("user",new User(username,password));
  49. }
  50. // Ask again for proper login
  51. else
  52. {
  53. forward = "/pages/login.jsp";
  54. }
  55. }
  56. //Forward
  57. this.getServletContext().getRequestDispatcher(forward).forward( pRequest,pResponse );
  58.  
  59. }

MY_SESSION_COOKIE cookie将保存JSESSIONID cookie的值。当JSESSIONID cookie被破坏时,MY_SESSION_COOKIE仍然存在会话ID。

JSESSIONID与Web浏览器会话不一致,但是我们选择使用持久和简单的cookie,以及放入应用程序上下文中的所有活动会话的映射。持久性cookie允许我们在地图中找到正确的会话。

不要忘记BalusC提供的这些有用的方法添加/获取/删除cookie:

  1. /**
  2. *
  3. * @author BalusC
  4. */
  5. public static String getCookieValue(HttpServletRequest request,String name) {
  6. Cookie[] cookies = request.getCookies();
  7. if (cookies != null) {
  8. for (Cookie cookie : cookies) {
  9. if (name.equals(cookie.getName())) {
  10. return cookie.getValue();
  11. }
  12. }
  13. }
  14. return null;
  15. }
  16.  
  17. /**
  18. *
  19. * @author BalusC
  20. */
  21. public static void addCookie(HttpServletResponse response,String name,String value,int maxAge) {
  22. Cookie cookie = new Cookie(name,value);
  23. cookie.setPath("/");
  24. cookie.setMaxAge(maxAge);
  25. response.addCookie(cookie);
  26. }
  27.  
  28. /**
  29. *
  30. * @author BalusC
  31. */
  32. public static void removeCookie(HttpServletResponse response,String name) {
  33. addCookie(response,name,null,0);
  34. }
  35.  
  36. }

最后一个解决方案是在本地主机上使用glassfish进行测试,在windows上使用chrome浏览器。它只取决于单个cookie,而不需要数据库。但实际上,我不知道这种机制的局限性是甚么。我只是晚上来到这个解决方案,而不知道这将是一个好还是坏的。

谢谢

我还在学习,请告诉我我的答案是否有错误。谢谢, @

猜你在找的HTML相关文章