【问题标题】:Is this a legitimate implementation of a 'remember me' function for my web app?这是我的网络应用程序“记住我”功能的合法实现吗?
【发布时间】:2011-02-11 21:28:29
【问题描述】:

我正在尝试向我的网络应用程序添加“记住我”功能,以让用户在浏览器重新启动之间保持登录状态。我想我得到了大部分。我在后端使用谷歌应用程序引擎,这让我可以使用 java servlet。下面是一些用于演示的伪代码:

public class MyServlet {
    public void handleRequest() {
        if (getThreadLocalRequest().getSession().getAttribute("user") != null) {
            // User already has session running for them.
        }
        else {
            // No session, but check if they chose 'remember me' during 
            // their initial login, if so we can have them 'auto log in' 
            // now.
            Cookie[] cookies = getThreadLocalRequest().getCookies();
            if (cookies.find("rememberMePlz").exists()) {
                // The value of this cookie is the cookie id, which is a 
                // unique string that is in no way based upon the user's 
                // name/email/id, and is hard to randomly generate.
                String cookieid = cookies.find("rememberMePlz").value();

                // Get the user object associated with this cookie id from 
                // the data store, would probably be a two-step process like:
                //
                // select * from cookies where cookieid = 'cookieid';
                // select * from users where userid = 'userid fetched from above select';
                User user = DataStore.getUserByCookieId(cookieid);
                if (user != null) {
                    // Start session for them.
                    getThreadLocalRequest().getSession()
                        .setAttribute("user", user);
                }
                else {
                    // Either couldn't find a matching cookie with the 
                    // supplied id, or maybe we expired the cookie on 
                    // our side or blocked it.
                }
            }
        }
    }
}

// On first login, if user wanted us to remember them, we'd generate 
// an instance of this object for them in the data store. We send the 
// cookieid value down to the client and they persist it on their side 
// in the "rememberMePlz" cookie.
public class CookieLong {
    private String mCookieId;
    private String mUserId; 
    private long mExpirationDate;
}

好吧,这一切都说得通。唯一可怕的是,如果有人发现了 cookie 的价值,会发生什么?恶意个人可以在他们的浏览器中设置该 cookie 并访问我的网站,并且基本上以与之关联的用户身份登录!

同样,我想这就是为什么 cookie id 一定难以随机生成的原因,因为恶意用户不必窃取某人的 cookie - 他们可以随机分配 cookie 值并开始以任何用户身份登录恰好与那个 cookie 相关联,如果有的话,对吧?

可怕的东西,我觉得我至少应该在客户端 cookie 中包含用户名,这样当它呈现给服务器时,除非用户名+cookieid 在数据存储中匹配,否则我不会自动登录。

任何 cmets 都会很棒,我对此很陌生,并试图找出最佳实践。我不是在写一个包含任何敏感个人信息的网站,但我想尽量减少任何滥用的可能性,

谢谢

【问题讨论】:

    标签: web-applications session servlets


    【解决方案1】:

    唯一可怕的是如果有人发现了 cookie 的价值会发生什么?恶意个人可以在他们的浏览器中设置该 cookie 并访问我的网站,并且基本上以与之关联的用户身份登录!

    没错。这也适用于所有“标准”会话 cookie,例如 JSP/Servlet webapps 中的 jsessionid 和 PHP webapps 中的 PHPSESSID 等等。然而,它们的寿命很短,不会造成伤害。对于长寿命 cookie,只需确保 cookie 值是唯一的(使用 DB 的 PK/UK)、长(最多 255 个字符)、难以猜测(没有模式、没有 MD5 哈希)并且可以包含所有可打印的 ASCII 字符(在 0x20-0x7E 范围内)。

    您还经常看到“仅在此 IP 地址上记住我”选项,因此它基本上锁定到一个唯一的 IP 地址。您可以通过HttpServletRequest#getRemoteAddr()获取。

    【讨论】:

    • 听起来不错,究竟什么是“DB 的 PK/UK”?这是一个实用程序库还是生成质量随机 cookie id 的东西?
    • PK = 主键(隐式唯一),UK = 唯一键。当您尝试插入副本时,数据库将出错。利用它:)
    猜你喜欢
    • 2010-10-15
    • 2012-08-08
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    相关资源
    最近更新 更多