【问题标题】:Proper usage of PHP Sessions正确使用 PHP 会话
【发布时间】:2014-07-31 17:00:21
【问题描述】:

我正在使用 PHP 和 MySQL 创建一个门户网站,供用户使用单点登录方法登录和访问各种工具。一些工具包括 phpMyAdmin 和 Piwik。登陆页面将显示他们无需单独登录即可使用的所有工具。

会话称为“门户”。

我有以下文件: index.php - 检查他们是否已登录。如果已登录,则会显示一个包含工具列表的页面。

login.php - 提供登录表单,创建会话,如果授权则重定向回 index.php

logout.php - 提供注销功能来销毁会话。

由于我在过去 4 年没有使用 PHP,我知道可能发生了很多变化。

以下是用于每个页面的脚本。

index.php

<?php
session_start();

if(!isset($_SESSION['user']) || (trim($_SESSION['pass']) == '')) {
header("location: login.php");
exit();
} else }
  // show list of tools (secure area)
}

?>

login.php

<?php
if (!empty($_POST)) {
  session_set_cookie_params(0, '/', '', 0); // NOT SURE WHAT THIS DOES?
  session_name("Portal");
  session_start();

  // check if credentials match
  ...code...

  // if credentials are ok
  $_SESSION['user'] = $_POST['user'];
  $_SESSION['pass'] = $_POST['pass'];
  session_write_close();
  header('Location: index.php');
} else {
  // show login form
}
?>

logout.php

<?php
session_start();
$_SESSION = array();
if (ini_get("session.use_cookies")) { // !not sure what all this below does!
  $params = session_get_cookie_params();
  setcookie(session_name(), '', time() - 4200,
  $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
}
session_destroy();
header('Location: http://.../index.php');
?>    

如何删除特定会话,即门户?我在根域有另一个登录名来访问报告,我不希望有权访问这两个会话的用户退出两个会话,而只是退出门户。

我的编码中是否有任何需要更改的内容以提高/增强安全性?

谢谢!

【问题讨论】:

  • 对于初学者,不要将用户的密码放在会话中。你也不需要显式调用session_write_close
  • 我根本不会这样做。为您的应用程序使用正确的 SSO 方法。如果他们没有,请不要这样做。不要将用户的密码重播到其他应用程序……它通常不起作用,而且根本不安全。
  • @Mark,确实存在会话和header 重定向的问题。在 5.2.x 之前,我一直在使用 PHP 的 Windows 环境中遇到这种情况。不过,我不知道这是否已修复。解决它的唯一方法是显式调用session_write_close
  • phpMyAdmin 支持单点登录。它请求将密码放入会话中(即 $_SESSION['PMA_single_signon_password'] = $_POST['pass']; )

标签: php session login session-cookies logout


【解决方案1】:

嗯,你的代码有一些问题。

首先,您必须调用session_name 之前 session_start(参见manual)。

另外,永远不要在会话中放入敏感数据

正如session_set_cookie_params 的文档中所说,您也可以调用session_start

session_set_cookie_params(3600, '/', '.yourdomain.com', false, true); // Notice the dot before the domain

这将允许您访问该域中所有应用程序中的会话。

我不知道您如何使用多个应用程序来完成这项工作,但如果它们支持单点登录,您将能够执行此操作无需在那里输入您的密码。

【讨论】:

  • 都在同一个 subdomain.example.com
  • 如果我无法存储密码,如何将我从用户那里收集的密码发送到 phpMyAdmin 等其他工具?
  • 您将尝试使用带有令牌验证的身份验证提供程序。请查看 oauth 2.0 ,这样您就不必移动密码(明文密码总是一个坏主意),而是可以移动令牌。
【解决方案2】:

您似乎没有任何服务器端验证。任何用户都可以在登录字段中插入他们想要的任何内容,然后访问“安全区域”,因为他们插入登录字段中的任何内容都在会话中。如果您没有验证任何内容,我建议将登录信息放入数据库中,当用户登录时,他们必须具有与数据库中的凭据相对应的匹配凭据。

此外,您的 index.php 页面的 else{} 括号朝向错误的方向。这应该会报错。

Index.php

<?php
session_start();

if(!isset($_SESSION['user']) || (trim($_SESSION['pass']) == '')) {
header("location: login.php");
exit();
} else {
  // show list of tools (secure area)
}

?>

【讨论】:

  • 我不想让帖子更长,所以我删除了检查凭据的部分。基本上,我使用 mysql 数据库和用户表作为有权访问门户的用户。
  • 哦,好的,凭据检查显然会使其更安全。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-24
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多