大家好,
提前道歉 - 我不是PHP专家,也不熟悉设计模式,所以这个问题可能有点基础...
无论如何,我正在开发一个需要登录的Web应用程序。
我的计划是这样的:
index.php:这个页面将包含一个简单的表格,允许用户输入用户名和密码。表格将把输入POST到...
login.php:这个页面将接收来自index.php的输入,并检查这些凭据是否与数据库匹配。如果任何输入缺失或凭证检查失败,php脚本将使用重定向将用户发送回index.php。
header('Location: http://www.mydomain.com/index.php');
如果凭据有效,则login.php会创建一个会话以建立用户的身份验证状态:
session_start();
$_SESSION['authenticated'] = true;
然后,它确定用户的访问类型。如果他具有“1级”访问权限,则脚本将使用以下方式将用户重定向到level1.php:
header('Location: http://www.mydomain.com/level1.php');
如果用户具有“2级”访问权限,脚本将使用以下方式将用户重定向到level2.php:
header('Location: http://www.mydomain.com/level2.php');
最后,当到达level1.php或level2.php时,它们首先要做的是检查会话。如果用户未经过身份验证,则将其重定向回index.php:
session_start();
if (!isset($_SESSION['authenticated']) {
header('Location: http://www.mydomain.com/index.php');
} else {
// proceed to display the page
}
在level1.php和level2.php中进行此检查将防止用户直接访问该页面,而不登录。我的第一个问题是:这个简单的逻辑第一次失败 - 当到达level1.php时,“isset($ _SESSION ['authenticated']”始终返回false,所以用户总是被重定向回index.php。如果他第二次输入完全相同的凭据,则该过程按预期工作。简言之,由于我不理解的原因,似乎login.php设置的会话在level1.php中找不到 - 我认为是因为重定向。换句话说,在未经往返到客户端浏览器的情况下,level1.php上的检查似乎会失败,直到/除非往返旅行被执行。由于每个需要登录的网站已经解决了这个问题,因此这不应该是一个新颖的挑战,并且应该有一个非常成熟的模式来解决它。我该如何处理它?相关问题...我以前看到过类似的问题,大多数答案通常涉及页面POST回自己的解决方案。这似乎有点奇怪 - 理想情况下,我希望每个PHP页面执行特定的工作:
- index.php - 显示一个表单以捕获凭据,然后将它们发布到login.php
- login.php - 评估用户的凭据,然后将他们引导到适当的页面
- level1.php和level2.php - 显示适当的内容
这是一个有缺陷的设置吗?如果是,那么更好的设置是什么?
一般来说,如果一个页面建立了一个会话,然后将用户重定向到另一个页面,那么第二个页面是否有办法读取会话?
维基百科上有一个很棒的页面关于Post/Redirect/Get:
http://en.wikipedia.org/wiki/Post/Redirect/Get
但对我来说有点抽象,我想看到具体页面的参考说明:例如,“页面A”上的表单将数据POST到“页面B”,“页面B”将用户重定向到“页面C”等。而且,如果在重定向时不识别会话,我不明白它是如何实现的。
非常感谢您提前的任何建议和见解。
[更新]
感谢Matt Ball的评论,我已经完善了这个问题:
login.php设置了会话并将用户重定向到下一个页面:
session_start();
$_SESSION['authenticated'] = true;
header('Location: http://www.mydomain.com/level1.php');
然而,当level1.php检查会话时,“authenticated”未被设置:
session_start();
echo (isset($_SESSION['authenticated']); // returns false
然而,如果我更改了login.php,使得header重定向到相对路径而不是绝对路径:
session_start();
$_SESSION['authenticated'] = true;
header('Location: level1.php');
然后,level1.php就像我期望的那样工作:
session_start();
echo (isset($_SESSION['authenticated']); // now returns true
我不明白为什么相对URL会有所不同,但它确实有所不同。所以,至少我的直接问题得到了解决。
非常感谢所有发表评论的人!
干杯, Matt Stuehler
session_start();
?另外,为了安全起见,不仅应该检查 level1...x.php 中的会话是否有效,还应该检查用户的级别是否足够。否则,Level1 用户可以登录,然后手动调用 level2.php。 - Select0r