Dar*_*nke 48 php authentication
在不使用CMS或繁重框架的情况下对用户进行身份验证的最佳库/方法有哪些?
响应应该包括您认为应该被视为涉及用户身份验证的新PHP开发标准的任何建议.
Sco*_*ski 13
安全地实施用户身份验证而不依赖于框架(或第三方库,如OpenID)来为您完成这项任务并非易事.
在10,000英尺的概述,你必须决定:
password_hash()或scrypt是要走的路.此答案中的信息与2015年5月9日相关并且是最新的,并且可能会因密码哈希竞争的结束而被淘汰
通常,用户名和电子邮件地址优于ID号.
应该没有安全要求来保持用户名的秘密,因为在实践中,当有人试图注册时,它们将被泄露.
您可以决定是否将电子邮件地址视为机密.用户通常喜欢不接触垃圾邮件发送者,诈骗者和巨魔.
你应该使用password_hash()并且password_verify()除非你有足够的经验来编写加密库以超越它.
有时开发人员喜欢创造性(例如添加"胡椒",这通常意味着使用静态密钥进行预先散列或HMACing密码)并超越标准实现.我们自己已经这样做了,但非常保守.
对于我们的内部项目(其安全性比大多数人的博客高得多),我们编写了一个围绕此API的包装器PasswordLock,首先使用密码哈希sha256,然后base64编码原始哈希输出,然后将此base64编码的哈希传递给password_hash(),最后使用正确实现的加密库加密bcrypt哈希.
重申一下,我们加密我们的密码哈希,而不是胡椒.这使我们在发生泄漏时更具灵活性(我们可以解密,然后重新加密,因为我们知道密钥).此外,我们可以在同一数据中心的不同硬件上运行我们的Web服务器和数据库,以减轻SQL注入漏洞的影响.(为了开始破解哈希,你需要AES密钥.即使你逃到文件系统,你也无法从数据库中获取它.)
// Storage:
$stored = \ParagonIE\PasswordLock\PasswordLock::hashAndEncrypt($password, $aesKey);
// Verification:
if (\ParagonIE\PasswordLock\PasswordLock::decryptAndVerify($password, $stored, $aesKey)) {
// Authenticated!
}
Run Code Online (Sandbox Code Playgroud)
PasswordLock:hash('sha256', $password, true);base64_encode($step1);password_hash($step2, PASSWORD_DEFAULT);Crypto::encrypt($step3, $secretKey);PasswordLock:Crypto::decrypt($ciphertext, $secretKey);hash('sha256', $password, true);base64_encode($step2);password_verify($step3, $step1);Mar*_*ork 11
我使用OpenID .
但是像stackoverflow一样,我使用Google项目openid-selector来完成繁重的工作.
演示页面在这里.
(OpenID)的明显优势是.
这里有很多很棒的答案,但我觉得值得这样说 - 在这种情况下不要试图重新发明轮子!以各种方式搞砸用户身份验证非常容易.除非您确实需要自定义解决方案,并且对安全方案和最佳实践有扎实的了解,否则您几乎肯定会遇到安全漏洞.
OpenID很棒,或者如果您打算自己动手,至少使用已建立的库并按照文档进行操作!
使用HTTP AUTH登录
经过身份验证后,对于PHP,您只需使用它$_SERVER['PHP_AUTH_USER']来检索身份验证期间使用的用户名.
这可以是比在脚本级别处理解决方案更快,有时更灵活的解决方案,前提是需要有关用户的有限信息,因为您可以使用的所有内容都是用于登录的用户名.
但是,除非您在脚本语言中实现完整的HTTP AUTH方案,否则不要将您的身份验证集成到HTML表单中(如下所述).
在脚本语言中滚动自己的HTTP AUTH
实际上,你可以扩展 HTTP基本认证通过模拟它在你的脚本语言.对此的唯一要求是您的脚本语言必须能够将HTTP标头发送到HTTP客户端.有关如何使用PHP完成此任务的详细说明,请参见此处:( 有关PHP和HTTP AUTH的更多信息,请参阅参考资料).
您可以使用典型的身份验证模式,文件存储,甚至PHP会话或cookie(如果信息不需要持久性)扩展上面的文章,在使用HTTP AUTH时提供更大的灵活性,同时仍保持一些简单性.
缺少HTTP AUTH
HTTP身份验证的主要缺点是退出可能会带来的复杂性.清除用户会话的主要方法是关闭浏览器,或者传递一个标题为403 Authentication Required.不幸的是,这意味着HTTP AUTH弹出窗口会返回页面,然后要求用户重新登录或点击取消.考虑到可用性时,这可能效果不佳,但可以使用一些有趣的结果(即使用cookie和HTTP AUTH组合来存储状态).
HTTP AUTH弹出窗口,会话和HTTP标头处理由浏览器实现标准确定.这意味着您将无法使用该实现(包括任何错误)而无法解决(与其他替代方案不同).
基本身份验证还意味着auth_user和密码显示在服务器日志中,然后您必须使用https进行所有操作,否则用户名和密码也会以纯文本格式在每个查询上通过网络.
将应用程序的安全层与其其余部分分开非常重要。如果您的应用程序逻辑和通信系统之间没有距离,您就可以在一个地方进行不安全的通信,而在其他地方进行安全的通信。也许您会犯一个错误并在未加密的 cookie 中发送密码,或者您可能会忘记验证用户的凭据。如果没有与用户沟通的“正确方式”,您肯定会犯错误。
例如,假设您现在验证用户的方式如下:
user_cookie = getSecureCookie()
if (user_cookie.password == session_user.password) {
do_secure_thing()
...
}Run Code Online (Sandbox Code Playgroud)
如果在 getSecureCookie() 中发现漏洞,并且您使用此代码来验证整个应用程序中的用户,则您可能找不到需要修复的所有 getSecureCookie() 实例。但是,如果您将逻辑与安全性分开:
if (userVerified()) {
do_secure_thing()
...
}
Run Code Online (Sandbox Code Playgroud)
...您将能够快速轻松地重新保护您的应用程序。给自己一个“正确的方法”来确保安全,那么您犯下重大安全错误的可能性就会大大降低。