【发布时间】:2020-10-05 08:21:49
【问题描述】:
我正在做一个简单的项目,我有一个包含多个用户的登录系统,每个用户都将登录并将表单条目保存在一个文件中。我正在尝试建立会话超时,以便在 2 分钟不活动后将我注销。
- 我有
login.php页面,我在其中提供了我的用户名和密码。 - 如果登录成功,它会将我重定向到
index.php页面,在该页面中我的表单带有两个文本框和一个按钮。 - 在
index.php页面上,我有Save Data按钮,如果我点击它会调用save.php,然后它会通过覆盖文件来保存表单条目。 - 我的
index.php页面上也有logout链接,如果我点击该链接,它会将我注销并重定向到login.php页面。
以上所有东西都可以正常工作。现在我正在尝试构建此会话超时,以便它可以在 x 分钟不活动后将我注销并将我重定向到 login.php 页面。
这是我的index.php 文件:
<?php
declare(strict_types = 1);
// Start session.
session_start();
// Include helper functions.
require_once 'helpers.php';
// 2 mins in seconds
$inactive = 120;
if(isset($_SESSION['timeout']) ) {
$session_life = time() - $_SESSION['timeout'];
if($session_life > $inactive)
{
redirect('logout.php');
return;
}
}
$_SESSION['timeout'] = time();
// Redirect user to login page if not authenticated.
if (! check_auth()) {
redirect('login.php');
return;
}
?>
<!doctype html>
<html>
<head>
<title>Home</title>
</head>
<body>
<div>
<h1>Website Title</h1> <a href="logout.php">Logout</a> </div>
<div>
<p>Welcome back, <?= $_SESSION['user_id'] ?>!</p>
</div>
<form method="post">
<input type="text" name="field1" />
<input type="text" name="field2" />
<input type="submit" name="submit" value="Save Data"> </form>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(function() {
$('form').submit(function(e) {
e.preventDefault();
$.post({
url: 'save.php',
data: $(this).serialize(),
}).done(response => {
response = JSON.parse(response);
if(response.message) {
alert(response.message);
}
});
});
});
</script>
</body>
</html>
这是我的save.php 文件:
<?php
declare(strict_types=1);
// Start session.
session_start();
// Include helper functions.
require_once 'helpers.php';
// 2 mins in seconds
$inactive = 120;
if(isset($_SESSION['timeout']) ) {
$session_life = time() - $_SESSION['timeout'];
if($session_life > $inactive)
{
redirect('logout.php');
return;
}
}
$_SESSION['timeout'] = time();
// Redirect user to login page if not authenticated.
if (! check_auth()) {
redirect('login.php');
return;
}
// save form entries in a file
这是我的helpers.php 文件:
<?php
declare(strict_types=1);
if (! function_exists('check_auth')) {
function check_auth(): bool
{
return isset($_SESSION['user_id']);
}
}
if (! function_exists('logout'))
{
function logout()
{
if (isset($_SESSION['user_id'])) {
$trace = json_decode(file_get_contents('current_user.txt'));
if ((int) $trace->user_id === $_SESSION['user_id']) {
$content = isset($trace->revoked_user_id)
? json_encode(['user_id' => $trace->revoked_user_id, 'created_at' => (new DateTime('now'))->format('Y-m-d H:i:s')])
: '';
file_put_contents('current_user.txt', $content);
}
unset($_SESSION['user_id']);
unset($_SESSION['timeout']);
}
}
}
if (! function_exists('redirect')) {
function redirect(string $url, int $status_code = 303): void
{
header('Location: ' . $url, true, $status_code);
die();
}
}
问题陈述
一旦index.php 和save.php 空闲2 分钟,我将重定向到logout.php 文件。这是我注意到的 -
- 如果我在
index.php页面上并且在 2 分钟不活动后,如果我刷新浏览器,那么它会正常注销我,没有任何问题,并将我重定向到login.php页面。 - 现在假设如果我再次在
index.php页面上,并且在我点击Save Data按钮后 2 分钟不活动后,它会在我的控制台上出现错误,但从技术上讲,它应该让我退出并重定向我登录.php 页面。
下面是我在index.php 页面中的 ajax 调用 -
<script>
$(function() {
$('form').submit(function(e) {
e.preventDefault();
$.post({
url: 'save.php',
data: $(this).serialize(),
}).done(response => {
response = JSON.parse(response);
if(response.message) {
alert(response.message);
}
});
});
});
</script>
每当我在 2 分钟不活动后单击 Save Data 按钮时,都会收到第 2 点的 json 解析错误。 response 变量的值在 html 中是完整的 login.php。我不确定为什么会这样。在调用save.php 之前,我们是否需要在 jquery 本身中检查会话验证?
【问题讨论】:
-
嗨,有趣,也许使用 PHP 的内置会话超时。这可能很有趣stackoverflow.com/questions/520237/…
-
我也试过了,如果我点击
Save Data按钮也会发生同样的事情,我得到一个错误,与我提到的相同的无效 json 错误。我认为在调用 save.php 文件之前,我需要在我的 ajax 调用中检查会话有效性?
标签: php ajax session session-timeout