我最后一天一直致力于一个迷你项目。
它是一个菜单界面,有4个子菜单部分。
每个子菜单在单击时都会请求单独的HTTP身份验证。
如果用户提交了正确的身份验证,则子菜单会解锁"。否则子菜单将保持锁定状态。
我已经让它发挥作用,我明白为什么它有效但和这个是我的问题 - 看起来有点hacky < / strong>我怀疑可能有更优化的解决方案。
当我第一次编写菜单并弹出HTTP身份验证菜单时,有三个结果:
401 Unauthorised Page
(当然可以......)我希望菜单对用户保持可见,因此我通过添加以下内容来设置自定义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;
对于那些已经过身份验证和那些尚未通过身份验证且将要解锁的用户,行为现在 完全符合预期 一个子菜单然后:
但对于输入正确详细信息的用户,尽管他们现在已经过身份验证,但会将其重定向回带有$_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>
答案 0 :(得分:0)
我仍然不清楚在自定义401页面上使用javascript重定向(对于取消身份验证控制台的用户)是合法的方法还是构成一个方便的黑客,但我已经开始使用它了现在。
我将其称为身份验证三明治。
有用的,我意识到,而不是过于复杂的过程:
401 Unauthorised Page
401 Unauthorised Page
401 Unauthorised Page
的重定向。(荒谬复杂,不是吗?)
我可以用更简单的替代方法替换以上所有内容:
自定义<head>
的{{1}}中的javascript重定向,它访问中间页面,i)重新锁定子菜单;和ii)返回菜单
就是这样。
401 Unauthorised Page
很多,很多更简单,更直接。