gpt4 book ai didi

session - session 或Cookie困惑

转载 作者:行者123 更新时间:2023-12-03 12:24:31 25 4
gpt4 key购买 nike

我在某些网站上看到用户登录到自己的帐户,然后关闭浏览器。

关闭并重新打开后,浏览器及其帐户仍处于登录状态。

但是有些网站不能那样做。

我很困惑,它被认为是 session 或cookie?

如果我希望这样登录我的网站,是否必须设置session.setMaxInactiveInterval()cookie.setMaxAge()

最佳答案

*该答案有严重缺陷,请参阅注释。 *

您的问题是关于 session 跟踪的。

[部分1]: session 对象

HTTP请求是单独处理的,因此为了在每个请求之间保留信息(例如,有关用户的信息),必须在服务器端创建 session 对象。

有些网站根本不需要 session 。用户无法修改任何内容的网站将无需管理 session (例如,在线简历)。在这样的网站上,您不需要任何cookie或 session 。

创建 session :

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

设置/获取属性:

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

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

销毁 session :

如果闲置时间过多, session 将被自动销毁。 Look at this answer for more details。但是您可以手动注销 session ,例如注销操作:

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

[PART 2]:所以...加入黑暗面,我们有COOKIES吗?

cookies 来了。

JSESSIONID:

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

什么时候删除JSESSIONID?

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

请注意,该 session 是客户端无法访问的,但仍在服务器端运行。设置MaxInactiveInterval可使服务器在闲置时间过长时自动使 session 无效。

邪恶破坏JSESSIONID

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

<SCRIPT language="JavaScript" type="text/javascript">

function delete_cookie( check_name ) {
// first we'll split this cookie up into name/value pairs
// note: document.cookie only returns name=value, not the other components
var a_all_cookies = document.cookie.split( ';' );
var a_temp_cookie = '';
var cookie_name = '';
var cookie_value = '';
var b_cookie_found = false; // set boolean t/f default f
// var check_name = 'JSESSIONID';
var path = null;

for ( i = 0; i < a_all_cookies.length; i++ )
{
// now we'll split apart each name=value pair
a_temp_cookie = a_all_cookies[i].split( '=' );
// and trim left/right whitespace while we're at it
cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
// alert (cookie_name);

// if the extracted name matches passed check_name
if ( cookie_name.indexOf(check_name) > -1 )
{
b_cookie_found = true;
// we need to handle case where cookie has no value but exists (no = sign, that is):
if ( a_temp_cookie.length > 1 )
{
cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
document.cookie = cookie_name + "=" + cookie_value +
";path=/" +
";expires=Thu, 01-Jan-1970 00:00:01 GMT";
// alert("cookie deleted " + cookie_name);
}
}
a_temp_cookie = null;
cookie_name = '';
}
return true;
}
// DESTROY
delete_cookie("JSESSIONID");

</SCRIPT>

Give another look to this answer。使用JavaScript,可以读取,修改JSESSIONID,使其 session 丢失或被劫持。

[PART 3]:关闭浏览器后保持 session

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??



是 cookies

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

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



我们还看到 session.setMaxInactiveInterval()可以防止无限期地运行丢失的 session 。 JSESSIONID cookie cookie.setMaxAge()也不会带我们到任何地方。

对 session ID使用持久性cookie:

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

BalusC的
  • How to implement "Stay Logged In" when user login in to the web application
  • Ben Souther的
  • http://simple.souther.us/not-so-simple.html; ben@souther.us

  • 主要思想是在Servlet上下文中的Map中注册用户的 session 。每次创建 session 时,都会使用JSESSIONID值作为密钥将其添加到Map中;还创建了一个持久性cookie,以存储JSESSIONID值,以便在销毁JSESSIONID cookie之后找到 session 。

    关闭Web浏览器时,JSESSIONID被破坏。但是所有HttpSession对象的地址都已保存在服务器端的Map中,并且您可以使用保存在持久性cookie中的值来访问正确的 session 。

    首先,在您的web.xml部署描述符中添加两个侦听器。
    <listener>
    <listener-class>
    fr.hbonjour.strutsapp.listeners.CustomServletContextListener
    </listener-class>
    </listener>

    <listener>
    <listener-class>
    fr.hbonjour.strutsapp.listeners.CustomHttpSessionListener
    </listener-class>
    </listener>

    CustomServletContextListener在上下文初始化时创建一个映射。该映射将注册用户在此应用程序上创建的所有 session 。
    /**
    * Instanciates a HashMap for holding references to session objects, and
    * binds it to context scope.
    * Also instanciates the mock database (UserDB) and binds it to
    * context scope.
    * @author Ben Souther; ben@souther.us
    * @since Sun May 8 18:57:10 EDT 2005
    */
    public class CustomServletContextListener implements ServletContextListener{

    public void contextInitialized(ServletContextEvent event){
    ServletContext context = event.getServletContext();

    //
    // instanciate a map to store references to all the active
    // sessions and bind it to context scope.
    //
    HashMap activeUsers = new HashMap();
    context.setAttribute("activeUsers", activeUsers);
    }

    /**
    * Needed for the ServletContextListener interface.
    */
    public void contextDestroyed(ServletContextEvent event){
    // To overcome the problem with losing the session references
    // during server restarts, put code here to serialize the
    // activeUsers HashMap. Then put code in the contextInitialized
    // method that reads and reloads it if it exists...
    }
    }

    创建 session 时,CustomHttpSessionListener会将 session 放入activeUsers映射中。
    /**
    * Listens for session events and adds or removes references to
    * to the context scoped HashMap accordingly.
    * @author Ben Souther; ben@souther.us
    * @since Sun May 8 18:57:10 EDT 2005
    */
    public class CustomHttpSessionListener implements HttpSessionListener{

    public void init(ServletConfig config){
    }

    /**
    * Adds sessions to the context scoped HashMap when they begin.
    */
    public void sessionCreated(HttpSessionEvent event){
    HttpSession session = event.getSession();
    ServletContext context = session.getServletContext();
    HashMap<String, HttpSession> activeUsers = (HashMap<String, HttpSession>) context.getAttribute("activeUsers");

    activeUsers.put(session.getId(), session);
    context.setAttribute("activeUsers", activeUsers);
    }

    /**
    * Removes sessions from the context scoped HashMap when they expire
    * or are invalidated.
    */
    public void sessionDestroyed(HttpSessionEvent event){
    HttpSession session = event.getSession();
    ServletContext context = session.getServletContext();
    HashMap<String, HttpSession> activeUsers = (HashMap<String, HttpSession>)context.getAttribute("activeUsers");
    activeUsers.remove(session.getId());
    }

    }

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

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title><bean:message key="formulaire1Title" /></title>
    </head>
    <body>
    <form action="login.go" method="get">
    <input type="text" name="username" />
    <input type="password" name="password" />
    <input type="submit" />
    </form>
    </body>
    </html>

    好了当用户不在 session 中时,此java servlet将转发到登录页面,当用户不在 session 中时,它将转发到另一个页面。它仅用于测试持久 session !
    public class Servlet2 extends AbstractServlet {

    @Override
    protected void doGet(HttpServletRequest pRequest,
    HttpServletResponse pResponse) throws IOException, ServletException {
    String username = (String) pRequest.getParameter("username");
    String password = (String) pRequest.getParameter("password");
    // Session Object
    HttpSession l_session = null;

    String l_sessionCookieId = getCookieValue(pRequest, "JSESSIONID");
    String l_persistentCookieId = getCookieValue(pRequest, "MY_SESSION_COOKIE");

    // If a session cookie has been created
    if (l_sessionCookieId != null)
    {
    // If there isn't already a persistent session cookie
    if (l_persistentCookieId == null)
    {
    addCookie(pResponse, "MY_SESSION_COOKIE", l_sessionCookieId, 1800);
    }
    }
    // If a persistent session cookie has been created
    if (l_persistentCookieId != null)
    {
    HashMap<String, HttpSession> l_activeUsers = (HashMap<String, HttpSession>) pRequest.getServletContext().getAttribute("activeUsers");
    // Get the existing session
    l_session = l_activeUsers.get(l_persistentCookieId);
    }
    // Otherwise a session has not been created
    if (l_session == null)
    {
    // Create a new session
    l_session = pRequest.getSession();
    }

    //If the user info is in session, move forward to another page
    String forward = "/pages/displayUserInfo.jsp";

    //Get the user
    User user = (User) l_session.getAttribute("user");

    //If there's no user
    if (user == null)
    {
    // Put the user in session
    if (username != null && password != null)
    {
    l_session.setAttribute("user", new User(username, password));
    }
    // Ask again for proper login
    else
    {
    forward = "/pages/login.jsp";
    }
    }
    //Forward
    this.getServletContext().getRequestDispatcher(forward).forward( pRequest, pResponse );

    }

    MY_SESSION_COOKIE cookie将保存JSESSIONID cookie的值。当JSESSIONID cookie被销毁时,MY_SESSION_COOKIE仍在其中,带有 session ID。

    JSESSIONID与Web浏览器 session 一起消失了,但是我们选择使用一个持久且简单的cookie,以及放置在应用程序上下文中的所有 Activity session 的映射。持久性cookie允许我们在 map 上找到正确的 session 。

    不要忘了BalusC制作的这些有用的方法,用于添加/获取/删除cookie:
    /**
    *
    * @author BalusC
    */
    public static String getCookieValue(HttpServletRequest request, String name) {
    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
    for (Cookie cookie : cookies) {
    if (name.equals(cookie.getName())) {
    return cookie.getValue();
    }
    }
    }
    return null;
    }

    /**
    *
    * @author BalusC
    */
    public static void addCookie(HttpServletResponse response, String name, String value, int maxAge) {
    Cookie cookie = new Cookie(name, value);
    cookie.setPath("/");
    cookie.setMaxAge(maxAge);
    response.addCookie(cookie);
    }

    /**
    *
    * @author BalusC
    */
    public static void removeCookie(HttpServletResponse response, String name) {
    addCookie(response, name, null, 0);
    }

    }

    最后一个解决方案在localhost上使用glassfish进行了测试,在Windows上使用chrome用于webbrowser进行了测试。它仅取决于单个cookie,并且您不需要数据库。但是实际上,我不知道这种机制的局限性。我只花了一整夜的时间来解决这个问题,却不知道它是好是坏。

    谢谢

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

    关于session - session 或Cookie困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16099752/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com