我有一个 PHP/MySQL 网站(网站 1),它的登录系统只要求输入 PIN 码(只是一个长数字字符串)。用户有两种使用此代码登录的方式:
直到这里一切正常。
现在问题来了。我想知道在使用上述第二种方法时,是否可以只允许登录(假设 PIN 正确) 仅当在特定网站 中单击该链接时。
它现在的工作方式是,任何拥有链接的人都可以使用它登录网站 1。我想防止这种情况发生,如果点击该链接赢得网站 2,我想允许这种情况发生。
这个想法是在登录功能中“检测”引用网站,并且只有在它与网站 2 的 URL(或任何其他唯一标识符)匹配时才允许它。
如果使用“普通”链接不允许这样做,那不会有问题,我可以灵活地使用什么方式来实现这一点,但最终它需要是只意味着点击的东西2.网站用户
编辑
我认为添加这一点很好,因为一些评论/回复谈到了这样做的安全性(这当然很棒)。这样做的主要原因是“强制”用户在访问网站 1 之前访问网站 2。基本上,他们无法在浏览器中输入该 URL 并登录网站 1,我只想能够使用它链接,如果他们从网站 2 单击它。我解释这一点,因为安全性在这里不是一个重要因素,如果一些精明的用户可以绕过我实现的任何方法,这没什么大不了的,更重要的是方法要简单尽可能在网站 2 中实现(因为我不运行该网站,我需要请那里的人做任何需要的事情)。
最佳答案
我认为您正在寻找单点登录的变体。这是一种技术,其中一个站点中的身份验证在另一个站点中被透明识别。这是它在您的情况下的工作方式。
通常,您在 site2.com 中会有一个这样的链接:
但是,site1.com 无法从推荐人那里得知它真正来自哪个站点,因为它可以被轻易伪造。当然,如果您只想要一个简单的安全级别,这对您的用例来说可能无关紧要。但如果你想要更好的东西,请继续阅读!
您可以使用散列系统和共享 secret 来创建只能来自一个来源的东西。两个站点都有相同的共享 secret ,存储在一个文件中。我们将其称为
$sharedSecret
。算法是这样的:$hash = hashFunction($pin . $sharedSecret);
然后您可以在 site2.com 中执行此操作:
<a
href="http://site1.com/login.php?pin=<?php echo (int) $pin ?>&hash=<?php echo $hash ?>"
alt="Authenticated link"
>
当 site1.com 看到它时,它可以立即获取 PIN,重复该算法,并检查哈希值是否确实来自 site2.com。如果您有多个引用站点,那么 site1.com 应该为所有这些站点存储一个单独的 secret ,然后它可以安全地检查引用站点以查看它应该加载哪个。
共享的 secret 应该足够大,不能被猜到;我倾向于使用大约 40-60 个字符。
然而,该计划的剩余缺陷是有人可以访问 site2.com 并从他们那里窃取链接,并且它仍然有效,前提是他们也愿意在每次想要访问时伪造推荐人。因此,在算法中添加时间戳也可能很有用:
// The time is rounded to the nearest 500 seconds, to account for
// out of sync clocks. Adjust this depending on how long you want links to
// remain active for
$time = floor(time() / 500) * 500;
$hash = hashFunction($pin . $sharedSecret . $time);
然后在 site1.com 上,您应该计算两个哈希值:
floor(time() / 500) * 500
floor(time() / 500) * 500 - 500
如果提供的哈希匹配,则允许链接解锁内容。这说明了时间在一台服务器和下一台服务器之间超过 +/-500 边界的可能性。
我这里没有提到特定的散列函数。 SHA256 应该没问题,但请注意我不是密码学家。如果您再次想要更高的安全性,可能值得检查以确保有人不会通过用猜测淹没您的系统来强制系统 - 尽管通过互联网这几乎不值得他们尝试。
关于php - 仅当请求来自另一个特定网站时才允许登录网站,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27323615/