使用PHP会话和Javascript进行HTTP身份验证 - 但我错了吗?

时间:2018-01-12 18:43:44

标签: javascript php authentication session-variables http-status-code-401

我最后一天一直致力于一个迷你项目。

它是一个菜单界面,有4个子菜单部分。

每个子菜单在单击时都会请求单独的HTTP身份验证。

如果用户提交了正确的身份验证,则子菜单会解锁"。否则子菜单将保持锁定状态。

我已经让它发挥作用,我明白为什么它有效但这个是我的问题 - 看起来有点hacky < / strong>我怀疑可能有更优化的解决方案

TLDR;直接进入第六步(下面)

第一步

当我第一次编写菜单并弹出HTTP身份验证菜单时,有三个结果

  1. 如果用户回复错误,则再次请求身份验证
  2. 如果用户给出了正确的回复,则子菜单会解锁
  3. 如果用户 取消 ...浏览器会显示401 Unauthorised Page(当然可以......)
  4. 第二步

    我希望菜单对用户保持可见,因此我通过添加以下内容来设置自定义401 Unauthorised Page

    ErrorDocument 401 /my-custom-401/
    

    到我的.htaccess文件

    而且,由于它是一个PHP文件,我添加了一个Location头重定向:

    header('Location: http://'.$_SERVER['HTTP_HOST'].'/my-menu/');
    exit();
    

    到文件的顶部。

    不。你知道那是什么吗?它可以防止身份验证控制台弹出。为什么?因为,在控制台弹出的位置,服务器已经访问自定义401 Unauthorised Page(即使它没有显示在浏览器中,直到您单击取消)。因此,如果服务器看到的第一件事是Location头,它就会在它弹出控制台之前离开。

    第三步

    所以,我写了一些html(<head><body>等),抛弃了PHP Location Header并添加了javascript重定向到<head>

    <script>window.location.href = '/my-menu/';</script>
    

    绝对好,虽然现在,鉴于我已经解锁了子菜单(这是幕后的默认行为 - 对于那些已经通过身份验证并且不需要再次通过身份验证的用户),现在发生的是只需在控制台上按取消,意味着我返回菜单,(当然)子菜单现在已解锁。

    第四步

    所以,我回到我的自定义401 Unauthorised Page重新锁定子菜单(我已经为不需要身份验证的用户解锁了)重定向。我使用 PHP会话,所以它看起来像这样:

    $_SESSION['My_Submenu_Unlocked'] = FALSE;
    

    对于那些已经过身份验证那些尚未通过身份验证且将要解锁的用户,行为现在 完全符合预期 一个子菜单然后:

    1. 输入错误的详细信息;的
    2. 按取消
    3. 但对于输入正确详细信息的用户,尽管他们现在已经过身份验证,但会将其重定向回带有$_SESSION['My_Submenu_Unlocked'] = FALSE;标记的菜单,这意味着子菜单不显示为已解锁...甚至虽然如果他们再次点击它(进行身份验证),菜单将会解锁。

      第五步

      点击某些内容并没有出色的用户体验,让它无所事事,然后再次点击它时会做出反应。我想在第一次点击它时解锁子菜单。为此,我想,服务器(或浏览器)需要识别用户刚刚从自定义401 Unauthorised Page重定向,然后在相应的子菜单上自动单击以提供预期的行为。

      自动点击不是问题 - 我可以在javascript中使用.click()执行此操作。但很快就变得很明显,如果浏览器在从自定义401 Unauthorised Page 重定向后触发了javascript而没有进一步的条件检查那么任何人在认证控制台上点击取消都会发现自己处于无限状态身份验证请求循环,始终被重定向到菜单,然后重定向到自定义401 Unauthorised Page等等......

      第六步

      ...就在那时我偶然发现了可能是黑客的问题,或者可能是一个优雅的解决方案,利用首先处理PHP的标准服务器行为,然后服务器等待正面的用户身份验证只有这样才能将HTML,CSS和Javascript传递给浏览器。

      在这里。在自定义401 Unauthorised Page的顶部,我有以下PHP,HTML和Javascript:

      <?php
      
      session_start();
      
      echo '<!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="utf-8">
      <title>My Custom 401 Unauthorised Page</title>
      ';
      
      // CONFIRM THAT SERVER HAS VISITED "401 UNAUTHORISED" AUTHENTICATION PAGE
      $_SESSION['Authorisation_Check'] = TRUE;
      
      // AUTHORISATION INSTRUCTIONS
      $_SESSION['Selected_Submenu_Unlocked'] = FALSE;
      
      // JAVASCRIPT REDIRECT FOR WHEN AUTHENTICATIONS ARE CANCELLED BY THE USER
      echo '<script>window.location.href = \'/my-menu/?locked\';</script>';
      
      echo '
      <link rel="stylesheet" href="/my-styles.css" />
      </head>
      ';
      

      上面javascript重定向中的查询字符串?locked就是我需要确保在返回菜单 自动点击 em> 用户按下取消。为什么?因为,显然,如果用户 ,则只会处理javascript重定向(使用查询字符串)。

      如果用户正确填写了身份验证详细信息,服务器仍会通过<head>进行解析,请注意:

      // CONFIRM THAT SERVER HAS VISITED "401 UNAUTHORISED" AUTHENTICATION PAGE
      $_SESSION['Authorisation_Check'] = TRUE;
      
      // AUTHORISATION INSTRUCTIONS
      $_SESSION['Selected_Submenu_Unlocked'] = FALSE;
      

      但是,在用户正确响应控制台之后,它会在浏览器进入处理之前返回到菜单URL(没有查询字符串):

      // JAVASCRIPT REDIRECT FOR WHEN AUTHENTICATIONS ARE CANCELLED BY THE USER
      echo '<script>window.location.href = \'/my-menu/?locked\';</script>';
      

      我可以看出为什么会这样,但这真的可靠吗?

      或者,PHP执行和Javascript执行的分离(中间是HTTP身份验证)是一种足够强大的方法,可以在将来使用和重用吗?

      无论哪种方式,还有更好,更优化的方法仍在使用 HTTP身份验证 PHP会话,但这并不涉及这种棘手的JavaScript?< / p>

1 个答案:

答案 0 :(得分:0)

我仍然不清楚在自定义401页面上使用javascript重定向(对于取消身份验证控制台的用户)是合法的方法还是构成一个方便的黑客,但我已经开始使用它了现在。

我将其称为身份验证三明治

有用的,我意识到,而不是过于复杂的过程:

  1. 重新锁定自定义401 Unauthorised Page
  2. 上的子菜单
  3. 将访问标记为自定义401 Unauthorised Page
  4. 通过javascript重定向回到带有附加查询字符串的菜单
  5. 处理菜单页上的条件块,如果刚出现自定义401 Unauthorised Page的重定向。
  6. 如果,请检查是否有追加到该网址的查询字符串。
  7. 如果不是,则使用javascript再次点击子菜单。
  8. 荒谬复杂,不是吗?)

    我可以用更简单的替代方法替换以上所有内容:

    自定义<head>的{​​{1}}中的javascript重定向,它访问中间页面,i)重新锁定子菜单;和ii)返回菜单

    就是这样。

    • 无需标记对自定义401 Unauthorised Page
    • 的访问
    • 不需要任何查询字符串
    • 菜单页面上不需要条件块
    • 无需过度使用javascript再次点击选定的子菜单

    很多,很多更简单,更直接。