我正在使用PHP(Zend)和MySQL从头开始编写购物车程序。现在我正在实现客户购物车,我将购物车中的商品保存到我的数据库中的表格中。因此,表中的每个项目都包含以下字段:
item_id session_id some_other_details_fields
当用户访问网站时,我使用session_start()分配会话ID,如果他或她将某些内容添加到购物车中,我会在上面的表格中插入一行。
因此,当用户想要从购物车中编辑或删除某些内容时,他们可以执行以下操作:
MYDOMAIN /购物车/编辑?ITEM_ID = XXX
和
MYDOMAIN /购物车/删除?ITEM_ID = XXX
一个明显的问题是,用户可以故意更改XXX以访问其他商品信息或从其他购物车中删除商品。所以我想添加mydomain / cart / edit?item_id = XXX& sess_id = YYY来验证sess_id YYY是否与数据库中项目XXX的session_id匹配。
我不知道这是不是一个好习惯,如果使用会话ID验证用户身份就足够了。任何关于此的想法或参考都将受到高度赞赏。
编辑:
我想尽可能长时间(例如,长达1年)将项目保存在购物车中,因此我使用存储在Cookie中的会话ID来识别用户并保存他们的数据库中的购物车中的商品,以确保只要用户不清理其Cookie,它就不会丢失。 我认为会话通常用于存储用户数据的时间较短,并且可能不如数据库可靠,如果这是错误的,请告诉我。
对于注册用户,我为其购物车使用单独的表格,并使用user_id来识别它们。如果客人注册,我将从"客人购物车表中移动他们的商品"到#34;注册用户购物车表"。我不想使用可能会不时被意外清理的会话,而是更愿意手动清理客人购物车表"只是为了安心。
我是Zend的新手,所以我不太确定如何使用Zend类编写它。所以我决定用php来做这些事情。
如果我上面做的事情很愚蠢,请纠正我。 :)
答案 0 :(得分:1)
我无法完全理解你的设计。使用数据库建议永久存储,但将购物车绑定到会话意味着用户无法注册并保留购物车。
$_SESSION
。user_id
。user_id
将是可选的,$_SESSION
将包含cart_id
。此外,在URL中传输会话ID(早期PHP版本中的默认行为)被证明是错误的想法:无意中泄露会话数据太容易了(例如,通过向朋友发送链接)。
总结:通常不需要使用会话ID。
我刚注意到你的编辑:
我想尽可能长时间地将商品保存在购物车中(例如, 最多1年),所以我使用存储在cookie中的会话ID来识别用户 并将他们的项目保存在数据库中的购物车中,以确保它不会 只要用户不清理他们的cookie就会丢失。
因此,购物车实际上与PHP会话无关。使用会话ID作为购物车标识符会不必要地将整个会话功能与您的数据库购物车链接起来,并增加了许多额外的麻烦,但没有任何好处:
您需要更改默认会话设置,以便在浏览器重新启动时会话cookie保持不变。
您可以通过重复使用相同的ID数月来增加会话劫持的风险。
你确定你并不是指 cookie 而不是会话吗?可以生成一个非常长的随机字母数字标识符,将其存储到cookie中,并将其用作数据库表的辅助键。
跟进问题
就安全性而言,为每位客人仅生成一个长字母数字“GUID”就足够了,并且当他或她回来时使用该“GUID”来验证身份吗?
它不需要全局(GUID中的G),但我想它不会受到伤害。但是你需要定义“足够”。将数据绑定到IP地址或用户代理字符串会使攻击者更难获得访问权限,从而使用户更容易丢失数据。使用HTTPS只会使您更安全,您需要在任何地方使用HTTPS。
为了避免“GUID”冲突,有什么好处可以开始吗?我使用会话ID只是因为它会为我生成一个“GUID”。
很抱歉,会话ID不是GUID:它只是一个带有随机种子的加密哈希。但请想一想:赢得一个销售数字从00000到99999(即1/100000的机会)的彩票非常困难。如果您生成一个带有数字和26个英文字母的32个字符的字符串,则您有1/36 ^ 32 = 1.5787740357426709877210×10 -50 。
对于我的情况,何时使用会话(作为最佳做法)?如果这不是一个使用会话的好方案,我有点失落。非常感谢!
您可能已经使用会话进行用户登录或订单付款,原因很简单:由于HTTP是无状态协议,因此没有其他办法可以做到这一点。为什么不惜任何代价将购物车存放在会议中如此重要? ; - )
答案 1 :(得分:0)
其他人告诉你只使用会话,通常这是正确的方法。但是,如果你想要一个双系统“你可以创建一个帐户,但你没有被迫这样做”,我明白为什么你想要使用一个数据库(一个单一的购物车节省系统,两种类型的用户,具有注册人所需的永久性。)
因此,如果我理解您的意图是正确的,那么您希望在数据库中购买与用户ID相关的内容。但是,当用户选择不进行注册和/或登录时,您就会遇到问题。在这种情况下,我建议在会话中保存一些临时用户ID,以及一些标志(即$_SESSION["realUser"] = false;
)并使用它,就像它是真实的一样。为避免冲突,这些临时名称应该是唯一的。例如,它们可以以空格字符开头,我认为不允许使用常规用户ID。或者,您可以使用变量对$userId, $realUser
作为用户标识符,在这种情况下,$userId
可以与会话ID相同。
但是,连接到这些临时ID的购物车不会持续一年。删除会话后,用户将无法访问该数据。因此,这些数据可以在更短的时间内被修剪,而与普通用户相关的数据根本不需要修剪(因此,他们甚至可以在十年之后找到他们的购物车,尽管这样做不会'对我来说很有意义。)
如果我理解你错了而且你不想将注册用户与未注册的用户混在一起,只需将所有数据放入会话中,就像其他人所建议的那样忘记数据库。