0

我正在使用 PHP (Zend) 和 MySQL 从头开始​​编写购物车程序。现在我正在实现访客购物车,并将购物车中的物品保存到数据库中的表中。因此,表中的每个项目都有以下字段:

item_id session_id some_other_details_fields

当用户访问该网站时,我使用 session_start() 分配一个会话 ID,如果他或她将某些内容添加到购物车中,我会在上面的表格中插入一行。

因此,当用户想要编辑或删除购物车中的某些内容时,他们可以执行以下操作:

mydomain/cart/edit?item_id=XXX

mydomain/cart/delete?item_id=XXX

一个明显的问题是用户可以故意更改 XXX 以访问其他人的商品信息或从其他人的购物车中删除商品。所以我正在考虑添加 mydomain/cart/edit?item_id=XXX&sess_id=YYY 以验证 sess_id YYY 是否与数据库中项目 XXX 的 session_id 匹配。

我不知道这是否是一个好习惯,以及使用会话 ID 来验证用户身份是否就足够了。对此的任何想法或参考将不胜感激。

编辑:

  1. 我想尽可能长时间地保存购物车中的物品(例如,最多 1 年),所以我使用存储在 cookie 中的会话 ID 来识别用户并将他们的物品保存在数据库中的购物车中,以确保它不会被只要用户不清理他们的cookies,就会丢失。我在想会话通常用于在较短的时间内存储用户数据,并且可能不如数据库可靠,如果这是错误的,请告诉我。

  2. 对于注册用户,我为他们的购物车使用单独的表格,并使用 user_id 来识别他们。如果客人注册,我会将他们的物品从“客人购物车表”移动到“注册用户购物车表”。与其使用可能不时被意外清理的会话,我更愿意手动清理“客人购物车表”,只是为了省心。

  3. 我是 Zend 的新手,所以不太确定如何使用 Zend 类编写它。所以我决定对这些东西使用php。

如果我上面做的事情很愚蠢,请纠正我。:)

4

2 回答 2

1

我不能完全理解你的设计。使用数据库建议永久存储,但将购物车绑定到会话意味着用户无法注册和保留他们的购物车。

  • 如果购物车只是会话数据,它应该直接存储到$_SESSION.
  • 如果购物车是永久的,则键应该是user_id.
  • 如果您想要在用户注册时选择性地保存到数据库中的会话购物车,您可以使用这两种方法或只使用数据库。如果您选择后者,user_id它将是可选的并且$_SESSION将包含cart_id.

此外,在 URL 中传输会话 ID(早期 PHP 版本中的默认行为)被证明是一个错误的想法:很容易在不经意间泄露您的会话数据(例如,仅向朋友发送链接)。

总结一下:通常不需要使用会话 ID。


我刚刚注意到您的编辑:

我想尽可能长时间地保存购物车中的物品(例如,最多 1 年),所以我使用存储在 cookie 中的会话 ID 来识别用户并将他们的物品保存在数据库中的购物车中,以确保它不会被只要用户不清理他们的cookies,就会丢失。

所以购物车实际上与 PHP 会话无关。使用会话 ID 作为购物车标识符会不必要地将整个会话功能与您的数据库购物车相关联,并且会增加很多额外的麻烦而无济于事:

  • 您需要更改默认会话设置,以便会话 cookie 在浏览器重新启动后仍然存在。

  • 通过重复使用同一个 ID 数月来增加会话劫持的风险。

你确定你真的不是指cookie而不是session吗?生成一个很长的随机字母数字标识符,将其存储到 cookie 中,并将其用作数据库表的辅助键就可以了。


后续问题

在安全方面,为每位客人生成一个长字母数字“GUID”并在他或她回来时使用该“GUID”验证身份是否足够?

它不需要全局(GUID 中的 G),但我想它不会受到伤害。但是你需要定义“足够”。将数据绑定到 IP 地址或 User-Agent 字符串会使攻击者更难获得访问权限,并使用户更容易丢失数据。仅使用 HTTPS 使您需要在任何地方使用 HTTPS 更加安全。

为避免“GUID”冲突,有什么好的开始吗?我使用会话 ID 只是因为它会为我生成一个“GUID”。

抱歉,会话 ID 不是 GUID:它只是带有随机种子的加密哈希。但请想一想:出售数字从 00000 到 99999 的彩票(这是 1/100000 的机会)是非常困难的。如果你生成一个包含数字和 26 个英文字母的 32 个字符的字符串,你有 1 / 36^32 = 1.5787740357426709877210×10 -50

对于我的情况,我什么时候应该使用会话(作为最佳实践)?如果这不是使用会话的好场景,我有点迷失了。非常感谢!

您可能已经在使用会话进行用户登录或订单付款,原因很充分:因为 HTTP 是无状态协议,所以没有其他方法可以做到这一点。为什么不惜一切代价将购物车存储在会话中如此重要?;-)

于 2013-08-23T10:48:47.010 回答
0

其他人告诉你只使用会话,通常这是正确的方法。但是,如果您想要一个双系统“您可以创建一个帐户,但您不必这样做”,我明白您为什么要使用数据库(对于两种类型的用户来说,一个单一的购物车保存系统,具有注册者所需的持久性)。

因此,如果我理解您的意图,您希望在与用户 ID 相关的数据库中进行购买。但是,当用户选择注册和/或登录时,您就会遇到问题。在这种情况下,我建议在会话中保存一些临时用户 ID,以及一些标志 (ie $_SESSION["realUser"] = false;),并像使用它一样使用它。为避免冲突,这些临时名称应该是唯一的。例如,它们可以以空格字符开头,我认为常规用户 ID 不允许使用该字符。或者,您可以使用这对变量$userId, $realUser作为用户标识符,在这种情况下$userId可以与会话 ID 相同。

但是,连接到这些临时 ID 的购物车不会持续一年。一旦会话被删除,用户将无法访问该数据。因此,这些数据可以在更短的时间后被修剪,而与普通用户相关的数据则根本不需要修剪(因此,即使十年后他们也可以找到他们的购物车,尽管这样做不会'对我来说没有多大意义)。

如果我理解错了,并且您不想将注册用户与未注册用户混为一谈,只需将所有数据放在会话中并忘记数据库,正如其他人所建议的那样。

于 2013-08-23T11:03:58.453 回答