使用 PHP 创建数据库驱动的应用程序

第 5 课:添加安全功能。实现应用程序用户登录

此页上的内容适用于 NetBeans IDE 7.2、7.3、7.4 和 8.0

在本课中,将为许愿者实现登录功能。这会影响以下文件:

  • index.php
  • createNewWisher.php
  • editWishlist.php
  • db.php
实现登录功能包括以下步骤:
  1. 在创建许愿者后,在会话中保存许愿者 ID
  2. 验证尝试编辑愿望列表的用户是否登录
  3. 许愿者从 index.php 页中登录

当前文档是“在适用于 PHP 的 NetBeans IDE 中创建 CRUD 应用程序”教程的一部分。


来自上一课的应用程序源代码

MySQL 用户:单击此处以下载源代码,该代码反映了在完成上一课之后的项目状态。

Oracle 数据库用户:单击此处以下载源代码,该代码反映了在完成上一课之后的项目状态。

创建后在会话中保存许愿者 ID

会话是持久性存储,可用于将信息从一个页面传输到另一个页面,而无需使用 HTML 输入窗体。可通过预定义的 PHP 数组 $_SESSION 支持该功能。

为安全起见,在创建新的许愿者后,该许愿者将自动登录而无需填写窗体。因此,您需要修改 createNewWisher.php 文件以实现以下功能:

  • 将新许愿者添加到数据库中。
  • 打开会话。
  • 在会话中存储许愿者的名字。
  • 在将许愿者重定向到 editWishList.php 页时,传输会话中的许愿者名字。
createNewWisher.php 文件中,找到以下行:
WishDB::getInstance()->create_wisher($_POST["user"], $_POST["password"]);
然后,在其下输入以下代码块:
session_start();
$_SESSION['user'] = $_POST['user'];
该代码块启动一个会话,这意味着打开 $_SESSION 数组以输入或检索数据。然后,该代码在 $_SESSION 数组中添加一个元素。添加的元素包含一个值和标识符(键)。该值是新创建的许愿者名字,标识符是 "user"。然后,程序将许愿者重定向到 editWishList.php 页。

验证用户登录

当用户访问 editWishList.php 页时,应用程序应确认刚才在 createNewWisher.php 页上注册的同一个人访问了该页。

实现该功能包括两个步骤:

从会话中检索许愿者的名字

editWishList.php 的 PHP 块中的默认代码替换为以下内容:
session_start();
if (array_key_exists("user", $_SESSION)) {
    echo "Hello " . $_SESSION['user'];
}

该代码块打开 $_SESSION 数组以检索数据,并验证 $_SESSION 是否包含具有 "user" 标识符的元素。如果检查成功,该代码将输出欢迎消息。

检查是否正确实现会话:
  1. 运行 createNewWisher.php 文件,然后创建一个新的许愿者,例如,Jack。
    editWishList.php 打开,并显示 Hello Jack。
  2. 在浏览器中清除会话 Cookie,或者结束会话并从 IDE 中运行 editWishList.php
    editWishList.php 文件打开并显示 Hello,因为没有通过会话传输任何用户。这是不正确的,因为它允许未登录和未注册的人创建或编辑愿望列表。为了避免出现该问题,需要将用户重定向到 index.php 页。

重定向未登录的用户

将以下代码块添加到 editWishList.php 中的 if 子句之下:
else {
   header('Location: index.php');
   exit;
}

该代码将用户重定向到 index.php 页并取消 PHP 代码执行。

要检查是否正确实现了该功能,请运行 editWishList.php 文件。预期的结果是打开 index.php 页。

从 index.php 页中登录

从 index.php 页中登录包括两个步骤:

用于在 index.php 上登录的 HTML 窗体

index.php 文件中,在结束 </body> 标记前输入以下代码:
<form name="logon" action="index.php" method="POST" >
    Username: <input type="text" name="user">
    Password  <input type="password" name="userpassword">
    <input type="submit" value="Edit My Wish List">
</form>

注:您可以忽略来自 HTML 验证器的警告。

该代码显示一个 HTML 窗体,用于在文本字段中输入用户的名字和口令。当用户单击 "Edit My Wish List" 时,数据将传输到同一页,即 index.php。

登录验证

登录验证包括:

用户可以在启动应用程序时访问 index.php 页,从 editWishList.php 页中进行访问,或者在输入名字和口令后从 index.php 页中重定向时访问该页。

由于仅在最后一种情况下使用 HTML 请求方法 POST,因此,您始终可以了解用户访问 index.php 时所在的位置。

在 index.php 文件中,使用以下代码在 HTML 块上面创建一个 <?php ?> 块:
<?php

require_once("Includes/db.php");
$logonSuccess = false;

// verify user's credentials if ($_SERVER['REQUEST_METHOD'] == "POST") { $logonSuccess = (WishDB::getInstance()->verify_wisher_credentials($_POST['user'], $_POST['userpassword'])); if ($logonSuccess == true) { session_start(); $_SESSION['user'] = $_POST['user']; header('Location: editWishList.php'); exit; } } ?>

代码块顶部允许使用 db.php 文件,并使用 false 值初始化 $logonSuccess 变量。如果验证成功,该值将变为 true

验证用户凭证的代码先检查请求方法是否为 POST。如果请求方法是 POST,则在提交登录窗体后重定向用户。在这种情况下,代码块使用在登录窗体中输入的名字和口令调用 verify_wisher_credentials 函数。

verify_wisher_credentials 函数(在下一节中编写)检查 wishers 表中是否存在用户和口令与登录窗体中提交的值相匹配的记录。如果 verify_wisher_credentials 函数返回 true,则在数据库中注册一个具有指定名字和口令组合的许愿者。这表示验证成功,并且 $logonSuccess 将值更改为 true。在这种情况下,将启动一个会话并打开 $_SESSION 数组。该代码在 $_SESSION 数组中添加一个新元素。该元素包含一个值和标识符(键)。该值是许愿者的名字,标识符是 "user"。然后,该代码将用户重定向到 editWishList.php 页以编辑愿望列表。

如果 verify_wisher_credentials 函数返回 false,则 $logonSuccess 变量值保持为 false。将使用该变量值显示错误消息

verify_wisher_credentials 函数

要实现验证许愿者凭证的功能,您需要在 db.php 文件的 WishDB 类中添加一个新函数。该函数要求将名字和口令作为输入参数,并返回 0 或 1。

对于 MySQL 数据库,请输入以下代码块:
public function verify_wisher_credentials ($name, $password){
$name = $this->real_escape_string($name);
$password = $this->real_escape_string($password);
$result = $this->query("SELECT 1 FROM wishers WHERE name = '" . $name . "' AND password = '" . $password . "'"); return $result->data_seek(0); }

对于 Oracle 数据库,请输入以下代码块(由于 OCI8 没有等效的 mysql_num_rows,该代码是 get_wisher_id_by_name 的修改形式):

public function verify_wisher_credentials($name, $password) {
    $query = "SELECT 1 FROM wishers WHERE name = :name_bv AND password = :pwd_bv";
    $stid = oci_parse($this->con, $query);
    oci_bind_by_name($stid, ':name_bv', $name);
    oci_bind_by_name($stid, ':pwd_bv', $password);
    oci_execute($stid);
//Because name is a unique value I only expect one row
    $row = oci_fetch_array($stid, OCI_ASSOC);
    if ($row) 
        return true;
    else
        return false;
}

该代码块执行查询 "SELECT 1 FROM wishers WHERE Name = '" . $name . "'AND Password = '" . $password . "'" 并返回满足指定查询的记录数。如果找到此类记录,该函数将返回 true。如果在数据库中找不到此类记录,该函数将返回 false

显示错误消息

要允许应用程序显示错误消息,请输入以下 <? php ?> 代码块(在 index.php 的登录窗体中的输入字段之下、按钮之上):
<?php
  if ($_SERVER["REQUEST_METHOD"] == "POST") { 
      if (!$logonSuccess)
          echo "Invalid name and/or password";
  }
?>
该代码块检查 $logonSuccess 变量值;如果该值为 false,则显示一条错误消息。

测试从 index.php 页中登录

检查登录功能在主页 index.php 上是否正常工作:
  1. 运行应用程序。
  2. index.php 页上,在 "Username" 编辑框中输入 Tom,在 "Password" 编辑框中输入 Tim。
  3. 按 "Edit My Wish List"。将显示一条错误消息(请注意,下面的浏览器窗口宽度减小为 600px,其中添加了一些换行符):
    index.php 页显示错误消息:名称和/或口令不正确
  4. 在 "Username" 编辑框中输入 Tom,在 "Password" 编辑框中输入 tomcat。
  5. 按 "Edit My Wish list"。将显示 editWishList.php 页:
    index.php:成功登录

完成当前课程后的应用程序源代码

MySQL 用户:单击此处以下载源代码,该代码反映了在完成课程后的项目状态。

Oracle 数据库用户:单击此处以下载源代码,该代码反映了在完成课程后的项目状态。

后续步骤

<< 上一课

下一课 >>

返回到教程主页



要发送意见和建议、获得支持以及随时了解 NetBeans IDE PHP 开发功能的最新开发情况,请加入 邮件列表

返回至 PHP 学习资源

get support for the NetBeans

Support