Php 如何生成mysql表中引用会话的唯一会话密钥?

Php 如何生成mysql表中引用会话的唯一会话密钥?,php,mysql,Php,Mysql,我使用$\u会话存储用户ID,但我想改为使用常规cookie(带密钥)与SQL配对,以便在用户关闭浏览器时对其进行身份验证 如何为会话表中的每一行创建一个唯一的键?您实际上希望编写自己的会话处理程序来绕过PHP在会话cookie上的cookie过期问题。这是非常简单的,如果做得好的话,这是非常优化的 步骤1:生成会话ID 会话ID是唯一的。但是,如果您计划进行永久会话,您必须记住两件事:您希望会话在每个浏览器上进行,而不管连接问题如何。因此,您可以通过将会话ID映射到导航器的用户代理(不会更改)

我使用$\u会话存储用户ID,但我想改为使用常规cookie(带密钥)与SQL配对,以便在用户关闭浏览器时对其进行身份验证


如何为会话表中的每一行创建一个唯一的键?

您实际上希望编写自己的会话处理程序来绕过PHP在会话cookie上的cookie过期问题。这是非常简单的,如果做得好的话,这是非常优化的

步骤1:生成会话ID

会话ID是唯一的。但是,如果您计划进行永久会话,您必须记住两件事:您希望会话在每个浏览器上进行,而不管连接问题如何。因此,您可以通过将会话ID映射到导航器的用户代理(不会更改)来欺骗系统

这允许您减少会话ID生成器为两个不同的访问者生成相同ID的机会。剩下的是一个随机数生成器和一个哈希算法,不过-
md5(microtime()。$\u SERVER['REMOTE\u ADDR'])
通常是一个值得信任的朋友

步骤2:存储和检索数据

存储数据也很简单。您的目标是创建一个至少包含两列的MySQL表:会话键(设置为
PRIMARY
)和数据(最简单形式的序列化数组,存储为
TEXT

创建会话时,只需插入新行并注意错误。如果出现错误,说明密钥已被使用,因此需要重新生成另一个密钥。如果该行插入成功-一切正常,则用户现在有一个会话行!从那以后,您需要做的就是按照您认为合适的方式读/写此行

使用会话ID对用户进行Cookie,就完成了

注意事项

  • 永远不要使用用户ID作为会话ID。Cookie很容易被操纵。您希望cookie值是随机的,并且与用户完全分离。这应该是毫无意义的
  • 您需要编写清理代码来不时清理会话表。这样做的一个好方法是跟踪上次使用会话的时间,并相应地删除

    • 最好的方法是使用一些散列函数,实际上PHP也通过生成会话id来使用散列函数。 您可以使用以下内容:

      md5(microtime());
      
      您可以将更多的值组合在一起,例如随机数、用户代理、服务器名称或使用更强大的算法,如SHA2

      但对于唯一性,若并没有存储这样的散列,那个么您将始终需要查看表(当然,概率非常低)


      但是我会选择标准的
      session\u id()
      ,它可以完成所有的工作。

      您可以使用MySQL的
      UUID()

      如果要保持会话的活动状态,还可以使用PHP的
      会话\u set\u cookie\u params()


      不过,SQL解决方案有一个优点:您可以轻松地扩展到更多Web服务器。另一方面,您不能使用PHP的
      $\u SESSION
      数组,您必须自己编写会话。

      通常会话由内置的自动生成的会话ID标识。听起来像是在重新发明轮子?$\u会话cookie会在浏览器关闭时被删除。使用常规cookie和SQL来保持会话的活动性不是很常见吗?也许我没有得到一些你可以通过内置会话模块实现的东西。看看-你可以指定更长的生命周期。但是如果我简单地使用set_cookie,它们不容易修改吗?我的意思是,如果用户有一个名为USERID的cookie,并且他只是将ID更改为其他内容,那么他会自动获得对另一个用户的访问权限account@Liso22只有在浏览器关闭时,如果服务器以这种方式配置,会话才会被销毁。您可以将会话配置为在您选择的任何时间段内保持活动状态。可能我误解了。但是你的意思是我可以把session_id()和userID一起存储在数据库中,并保存在一个普通的cookie中,以供以后参考吗?我正在尝试创建一个相对安全的网站,需要在用户关闭浏览器时保持其日志安全性与cookies无关:-)我将编辑我的答案,因为我在这个小框中的空间不足。在这里!编辑。另外,我强烈建议不要使用默认的PHP会话系统。这是一个关于ASP站点的轶事,但同样是真的——当你想让不同的服务/服务器与会话无缝交互时,你必须重新发明轮子。还是早点做吧。太好了,谢谢你提供的所有信息。最终实施起来并不难。我只是在每一页中包含检查它的代码。只是一个关于你提到的清理的问题。我将使会话过期,并在每次加载页面时创建一个新会话。(我保留状态为'expired'的过期行)。作为“清理”,这就足够了吗?或者我应该使用cron作业或其他东西来不时清理表。(我想我以后可能会使用那些过期的行来计算页面浏览量或类似的东西)您希望在任何给定的时间拥有尽可能多的免费ID。这就是我建议的清理——否则,当您生成看似唯一的ID时,您将遇到越来越多的冲突,这绝不是一件好事。您要做的是彻底删除过期的会话,或者至少是非永久性会话。如果无法执行此操作,请向表中添加一个字段并将其命名为session_expired,将其设置为boolean。不是使用会话\ id进行索引,而是使用会话\ id进行索引,会话\已过期。这将为您提供两倍的范围,但不会减少数据库查找时间。我可以关闭会话吗?我认为这是不可能的。你能解释一下怎么做吗?这里有很好的记录:。也检查评论。有人写了一个漂亮的三行程序来刷新e上的会话