IT技术之家 发表于 2020-10-4 17:48:15

PHP客户端注册,登录,注销和轻松访问控制

前言
自撰写本文以来的几年中,许多黑客攻击已将目标锁定在受密码保护的网站上。客户密码的存储已成为许多讨论的主题,其中一些有用,而另一些则被误导了。当然,没有人会以明文形式存储客户端密码,但是许多尝试的解决方案(消息摘要,加密等)都比明文略好。可在此处找到有关密码存储的配套文章:PHP中的密码哈希。以下讨论和文章部分“后记:关于存储密码”已过时,不应用作您的应用程序的基础。
介绍
对于新PHP开辟人员来说,常见的设计模式题目是这样的:“如何处理客户端注册和登录?” 它在每个框架和CMS中都已完成,并且它们都使用类似的模式。本文逐步构建了模式,因此您可以查看代码各部分的内容。
对于此示例,我们依靠PHP会话处理程序来告诉我们客户端是否已登录。我们还使用cookie,以便“记着”客户端已登录,并且我们使用了包含客户端的数据库表信息。
我们对这种设计模式的实现使我们能够使用一行PHP代码对网页举行密码保护,如下所示:

access_control();

此外,我们可以使用以下方法测试客户端登录(实际上不需要登录):

if (access_control(TRUE)) { /* CLIENT IS ALREADY LOGGED IN */ }


本文结尾处有一些解释和后记。如果有时间,您可能需要向下滚动并立即阅读。当您尝试使用此设计时,它们会更深入地介绍您可能碰到的题目。然后回来并继承。
约定和标准
1.我们同意在所有页面上都使用session_start()的约定,没有例外。您可能希望将session_start()添加到通用脚本的顶部,该脚本会包含在所有页面脚本的顶部,以便您网站的每个页面都可以这样开始:

PLEASE REGISTER
CHOOSE USERNAME:
CHOOSE PASSWORD:
VERIFY PASSWORD:
KEEP ME LOGGED IN (DO NOT CHECK THIS ON A PUBLIC COMPUTER)



客户端身份验证-登录页面
现在我们可以注册用户,并且我们拥有测试页面,可让我们查看实际的注册,我们需要创建登录和注销页面。
登录页面使用类似于注册页面的布局。我们需要我们的“配置”页面,然后举行测试以查看是否提供了必要的凭据(第5行)。我们过滤并整理外部输入(第8-9行),然后查询数据库,在UID和PWD字段(第12-20行)中查找完全匹配的一个。如果找不到在UID和PWD上都匹配的行,则第20行的if()语句将失败,脚本将降落至第46行,在此我们可以告诉客户端身份验证失败,并可以显示登录名再次形成。如果确实找到了要查找的一行,则检索该行(第23行)并将UID值复制到会话数组(第26行)中,以显示客户端现在已登录。我们的下一步是查看是否客户选中了“记着我”框。我们测试该复选框(第29行),如果已选中该复选框,我们将调用Remember_me()函数,并通报在注册时创建的唯一用户密钥。Remember_me()函数可在欣赏器上设置一个长寿命的cookie。如果没有此cookie,则仅使用会话cookie来记着客户端。当欣赏器窗口关闭时,会话cookie也会过期。
登录处理的最后一步是确定客户端下一步要去哪里。我们通过测试会话数组中的“ entry_uri”来做到这一点。如果它是由配置脚本中的access_control()函数设置的,我们可以在header()命令中使用该地点将客户端带回到原始页面。如果未设置该选项(如果客户端直接进入登录页面,则会发生这种情况),我们可以改为重定向到主页。
也许应该不用说,但是我照旧要说:不要在您的登录脚本中放入access_control()函数,否则您的代码可能会导致服务器循环!这是登录脚本:

PLEASE LOG IN
UID:
PWD:
KEEP ME LOGGED IN (DO NOT CHECK THIS ON A PUBLIC COMPUTER)



客户端取消身份验证-退出页面
如果我们的客户端登录,并且未选中“记着我”框,则当欣赏器窗口关闭或会话垃圾网络例程检测到长时间不活动时,他将主动注销。 (通常约24分钟)。但是,我们的客户可能希望刻意注销,或者可能是在审慎的情况下在公共计算机上注销。因此,我们还必须提供一个注销脚本,如下所示。
与往常一样,我们的第一步是加载“ config”脚本。接下来,我们从会话数组中网络UID,或设置一个替代值。我们将在“再见”消息中使用此消息,因此,即使客户端一连两次登录注销脚本,或者试图以某种方式在客户端未登录时设法去到那里,我们都尝试选择一个有意义的数据字符串这是在三元运算符语句(第5行)中完成的。
我们处理“记着我” cookie(如果有的话)(第7-12行)。
下一步是清除会话数组(第15行)。这可能看起来有些一筹莫展,您可能会思量完全消除该会话是否有意义。如果即使在客户端注销后,会话中仍有其他信息要保留,则可以仅在第15行取消设置($ _SESSION [“ uid”])并跳过别的代码。但是,您永远不要使用unset($ _ SESSION)清除数组。请参阅此处的注意事项:
http : //php.net/manual/en/s ession.exa mples.basi c.php
最后,您可以使用我们在第5行创建的数据字符串说“再见”。欣赏器输出,而是激活标题(“位置:/”
看一下“出口”;最后一行的声明。只管这里并不是严酷要求的,但是在标题(“ Location”)语句之后使用“ exit”是一种养成的好习惯。为什么?因为您的脚本在发送header()之后将继承正常运行,并且将运行一段不可预知的时间-直到欣赏器收到该标头并通过重定向制止脚本。有很多适当的header()语句可以作为完整脚本的一部分内联使用,但是当您使用旨在作为脚本中最后一条语句的语句时,则需要采取额外的步调来确保它是,实际上是最后一条要执行的语句。这是注销脚本:

CHANGE YOUR PASSWORD
FORMER PASSWORD:
CHOOSE PASSWORD:
VERIFY PASSWORD:



简介-付诸实践
这就是使用根本的PHP身份验证来密码保护网页的所有步调。一旦有了这种布局,就可以显示公共注册和登录页面,并通过公共,受保护和部分受保护的网页的组合来构建站点。最紧张的是,您可以使用一行PHP代码举行身份验证测试。这些脚本使用PHP会话来标识已登录的客户端。客户可以要求您的网站记着他们的状态,您可以帮他们。他们可以随时注销,也可以在一段时间不活动后主动注销。他们可以随时更改密码来保护本身的帐户信息。
此处的解释和代码将在大多数PHP安装中正常运行,但是它们仅作为讲授示例,并不筹划在生产环境中“按原样”使用-因此,请随意复制和修改它们以得当您的特定需求。
后记:了解PHP会话
只管这些脚本以合理的方式使用PHP会话,但我发现很容易太过思考PHP会话的工作方式。它们比您预期的要容易得多!您可能需要阅读这两篇文章,以更好地了解我们的PHP客户端身份验证所依赖的基础技能。
关于PHP会话的文章。
有关 HTTP客户端/服务器协议的文章。
后记:防止主动注册
曾经想知道在线论坛如何获得这么多垃圾的伟哥广告吗?广告由“攻击”机器人脚本放置,这些脚本会找到注册表格并注册一个帐户,然后使用该帐户发布不需要的质料。联合使用两种技能可以减少这种入侵的风险。起首是在注册表上使用CAPTCHA测试。第二个是使用“握手”,这需要一个额外的步调来通过电子邮件中的阐明白认注册。这两种方法都可以单独有效。综合起来,它们以致更有效。
后记:MySQL和MySQL i (2014年春季)
本文最初写于几年前,当时PHP支持MySQL数据库扩展。此后发生了变化,如果您使用本文的旧版本作为引导,则可能需要更改脚本。幸运的是,如果选择面向对象的MySQL i,则更改非常容易完成。要了解PHP为什么取消MySQL支持,以及如何使脚本保持运行状态,请参阅这篇文章,该文章教您如何将过程式MySQL代码转换为MySQL i或PDO。
后记:PHP session_unregister() (2014年秋季)
一些过时的代码集包含使用session_unregister()函数的“注销”示例。PHP在很多年前不推荐使用此功能,而在最近将其删除。不幸的是,PHP代码示例没有到期日期,因此您可能会碰到没有任何告诫标签的过时代码。如果您有一个使用session_unregister()的脚本,则应使用雷同的函数调用参数将函数名称替换为unset()。今后,请勿使用session_unregister(),session_register()或session_is_registered()。要了解本文的别的部分,您可能想刷新有关PHP会话如何工作的记忆。
后记:关于存储密码
实际上,您不会以明文形式存储客户端密码。您可以使用PHP md5()函数对密码举行编码。 MD5是“消息摘要”的缩写。请在这里阅读评论。我差别意这样的观念,即如果您了解本身在做什么并且正确使用md5(),那么md5()哈希对于大多数用例来说是不够的。但是,许多专家赞成使用密码哈希。或至少是加密。这是我对md5()的看法。
1.假设您愚蠢地以明文形式存储了客户端密码。长处:当客户端忘记密码时,脚本可以发送客户端密码。缺点:如果您的数据库遭到破坏,则将公开所有客户端密码。
2.假设您没有存储明文密码,但是却愚蠢地存储了密码的md5()摘要。看起来像这样...
5f4dcc3b5aa765d61d8327deb8 82cf99
...这是“密码”的md5()。您不能仅通过查看就容易判断出此md5()字符串与“ password”匹配,但是md5()摘要的题目在于它们在编程上是幂等的。无论您对“密码”举行散列多少次,都将始终获得雷同的md5()字符串。如果两个人选择雷同的密码,则md5()字符串将雷同。黑客知道最受欢迎的密码md5()字符串,因此,如果您的数据库遭到破坏,则会暴露许多客户端密码。黑客知道多少个普通密码?您会信赖数百万吗?你最好信赖它!
3.如果让客户选择他们本身的密码,而其中一个选择“密码”,则黑客更有可能破译其他常用密码。与流行密码的md5()字符串匹配的暴力破解方法在计算上是微不足道的。每个字典单词与其md5()摘要匹配最多需要几秒钟。
4.为了使密码更难破解,一个子行业涌现出了各种各样的伏都教徒和关于密码学的废话。您可以制止废话,并从OWASP项目中了解更多信息。您可以使用密码哈希来增强密码安全性。
5.因为md5()是幂等的,所以安全性要求必须采取某些措施来破坏“密码”和5f4dcc3b5aa765d61d8327deb8 82cf99之间的直接链接。那是在编码过程中添加到密码的“盐”。在密码后面附加一个盐字符串,幂等关系不仅需要密码,还需要盐。因此,如果客户端选择“密码”,则服务器将存储诸如“密码XYZ ”之类的md5字符串,其效果摘要为cceef54fde042f058f57108433 8e2c40。比较这些md5字符串,看看是否可以看到关系。我不能
6.您的盐不必很容易猜测。但是必须将其存储在某个位置,以使其在脚本执行期间可以编程方式供PHP使用。您可能要警惕保护它。如果盐析字符串和算法遭到破坏,则可能暴露您客户的密码。也许您想将其放入存储在WWW根目录上方的PHP脚本中,并通过include()函数将其引入Web根脚本的范围。
7.您可以在密码的两头加盐(加盐和胡椒粉))。您可以使用非常长且任意的字符串来放入盐和胡椒。只要将雷同的盐和胡椒粉添加到客户端输入密码框中的任何内容,您的md5()算法就会创建幂等消息摘要。您可以使用简朴的SQL查询来匹配密码。
8. md5()冲突的可能性(两个差别的输入字符串匹配雷同的消息摘要)与您的DNA序列碰到其他人的可能性险些雷同。从理论上讲这是可能的,但不要赌钱。
9.加盐的密码有多坚固?我将向任何人买啤酒,谁能告诉我创建此md5()摘要的原始输入字符串:
e0f1299ed629d3c8826e2dd2be 4780cf
为了方便您搜刮原始输入字符串,这里是md5()算法阐明的链接。
http://www.faqs.org/rfcs/r fc1321.htm l
并且我已经在服务器上安装了此易于使用的脚本。在此处举行实验:
http : //www.iconoun.com/dem o / md5.php
10.如果您选择了好的盐和胡椒粉字符串并将其保密,则在大多数情况下,您的md5()摘要将足以保护客户端密码。但是你不能解决愚蠢的题目。如果客户选择“密码”,而您的登录过程仅需要一个电子邮件地点和密码,则没有太多保护该客户免于暴露的机会。内部如何对“密码”举行编码并不紧张。知道站点中电子邮件地点的任何人都可以尝试将每个人与“密码”或其他常用密码配对,以查看配对是否有效。毫无疑问,如果您的生齿足够多,则您的客户社区中会有人使用“密码”,并且她将成为任何攻击的首批受害者之一。
11.由于第10个原因,某些密码选择过程要求您使用字母和数字的组合,使用大写和小写等。我觉得这些令人讨厌,并且倾向于使用多字密码短语的概念。而不是一个密码。我敢肯定会有流行和常用的词组,并且明智的选择是在词组中选择随机单词,并包含一些以致根本不是单词的内容。高盐短语至少与高盐密码一样好。
12. md5()字符串始终为32个字符的十六进制数字,无论输入字符串包含什么内容。因此,数据库存储必须具有32字节的列宽。ArsTechnica的
这篇文章提供了内部人士对黑客可能如何攻击您的编码密码的看法。最终,您的密码就像是防火保险箱的门。根据时间和温度对它们举行评级。坚固的门意味着您有更多的时间来焚烧物品。不幸的是,像ArsTechnica所做的那样,每一项练习都将根本密码和密码短语添加到字典中,并且字典攻击是最快乐成的。
而您要保护的内容至关紧张。如果您有保龄球得分,购买历史,医疗纪录,财务细节或核发射代码,则安全措施可能会有所差别。
页: [1]
查看完整版本: PHP客户端注册,登录,注销和轻松访问控制