php - 仅当请求来自另一个特定网站时才允许登录网站

标签 php login referrer

我有一个 PHP/MySQL 网站(网站 1),它的登录系统只要求输入 PIN 码(只是一个长数字字符串)。用户有两种使用此代码登录的方式:

  • 转到网站 1 登录页面并在典型登录表单中输入代码
  • 在网站 2 中单击带有他的 PIN 码作为 GET 值的链接。该链接的格式为 http://myURL.com/login.php?pin=123456789 。这只是调用一个函数,该函数接收 PIN 作为参数并处理登录。 网站 2 与网站 1 位于不同的域/服务器中。

  • 直到这里一切正常。

    现在问题来了。我想知道在使用上述第二种方法时,是否可以只允许登录(假设 PIN 正确) 仅当在特定网站 中单击该链接时。

    它现在的工作方式是,任何拥有链接的人都可以使用它登录网站 1。我想防止这种情况发生,如果点击该链接赢得网站 2,我想允许这种情况发生。

    这个想法是在登录功能中“检测”引用网站,并且只有在它与网站 2 的 URL(或任何其他唯一标识符)匹配时才允许它。

    如果使用“普通”链接不允许这样做,那不会有问题,我可以灵活地使用什么方式来实现这一点,但最终它需要是只意味着点击的东西2.网站用户

    编辑

    我认为添加这一点很好,因为一些评论/回复谈到了这样做的安全性(这当然很棒)。这样做的主要原因是“强制”用户在访问网站 1 之前访问网站 2。基本上,他们无法在浏览器中输入该 URL 并登录网站 1,我只想能够使用它链接,如果他们从网站 2 单击它。我解释这一点,因为安全性在这里不是一个重要因素,如果一些精明的用户可以绕过我实现的任何方法,这没什么大不了的,更重要的是方法要简单尽可能在网站 2 中实现(因为我不运行该网站,我需要请那里的人做任何需要的事情)。

    最佳答案

    我认为您正在寻找单点登录的变体。这是一种技术,其中一个站点中的身份验证在另一个站点中被透明识别。这是它在您的情况下的工作方式。

    通常,您在 site2.com 中会有一个这样的链接:

    http://site1.com/login.php?pin=123456789



    但是,site1.com 无法从推荐人那里得知它真正来自哪个站点,因为它可以被轻易伪造。当然,如果您只想要一个简单的安全级别,这对您的用例来说可能无关紧要。但如果你想要更好的东西,请继续阅读!

    您可以使用散列系统和共享 secret 来创建只能来自一个来源的东西。两个站点都有相同的共享 secret ,存储在一个文件中。我们将其称为 $sharedSecret 。算法是这样的:
    $hash = hashFunction($pin . $sharedSecret);
    

    然后您可以在 site2.com 中执行此操作:
    <a
        href="http://site1.com/login.php?pin=<?php echo (int) $pin ?>&amp;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/

    相关文章:

    login - 在 Keycloak 禁用多重登录

    javascript - 在 IE 中获取页面引用的最可靠方法是什么?

    php - 将 JS 创建的输入文本框的值插入数据库

    php - 在 MYSQL 中按周/按月搜索数据

    login - phpstorm SSH 不会给我带来下一个按钮

    django - 如何判断 django 用户是否曾经登录过?

    javascript - 在 JavaScript 中隐藏/欺骗引荐来源网址的最可靠方法是什么?

    未填充 Android Market 引荐来源数据

    php - 项目编码标准与单元测试代码覆盖率冲突怎么办?

    php - 在 Doctrine 中使用 URL 字段