PHP PDO Prevent Action of Logged In (or Session) User

I’m working on trying to build an attendance application using PHP, PDO and MySQL. I currently have a table called users that just shows a list of users that can log into the application. The table structure is shown below.

I have an action column that shows two links: One to edit the user and one to delete the user.

image

The way my code is structured, I have it set to where any admin can delete users (as only admins can see this page), but I also have a problem. The code is written to where the admin can delete the account they are logged into and I don’t want that to happen by accident.

Based on this code:

<?php

include('nav/head.php');

if($role_id != '1') {
	header('Location: error.php');
	exit();
}

?>

<!DOCTYPE html>
<html lang="en">

<head>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">

  <title>CCRP | Users</title>

  <?php include('nav/header.php') ?>

          <!-- Page Heading -->
          <h1 class="h3 mb-2 text-gray-800">Users List</h1><br>
          <!-- <p class="mb-4">DataTables is a third party plugin that is used to generate the demo table below. For more information about DataTables, please visit the <a target="_blank" href="https://datatables.net">official DataTables documentation</a>.</p> -->

          <!-- DataTables Example -->
          <div class="card shadow mb-4">
            <div class="card-header py-3">
              <h6 class="m-0 font-weight-bold text-primary">Add, Edit or Remove User Accounts</h6>
            </div>
            <div class="card-body">
			<a class="btn btn-success" href="user_new.php"><i class="fa fa-user-plus"></i>&nbsp Add New User</a>
			<br><br>
              <div class="table-responsive">
                <table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
                  <thead>
                    <tr>
                      <th>User ID</th>
                      <th>User Role</th>
                      <th>First Name</th>
                      <th>Last Name</th>
                      <th>Email Address</th>
                      <th>Username</th>
					  <th>Status</th>
					  <th>Action</th>
                    </tr>
                  </thead>
				  <?php
				  
				  	$stmt = $pdo->prepare("SELECT id, role_id, first_name, last_name, email, username, status FROM users");
					$stmt->execute();
					while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
				  
				  ?>
				  	<tr>
						<td><?php print($row['id']) ?></td>
						<td>
						
						<?php 
						
						if ($row['role_id'] === '1') {
							echo 'Administrator';
						} elseif ($row['role_id'] === '2') {
							echo 'Operator';
						}
						
						?>
						
						</td>
						<td><?php print($row['first_name']) ?></td>
						<td><?php print($row['last_name']) ?></td>
						<td><?php print($row['email']) ?></td>
						<td><?php print($row['username']) ?></td>
						<td>
						
						<?php 
						
						if ($row['status'] === '1') {
							echo '<strong style="color: #009900;">Active</strong>';
						} elseif ($row['status'] === '0') {
							echo '<strong style="color: #a40000;">Inactive</strong>';
						}
						
						?>
						
						</td>
						<td>							
							<a href="user_edit.php?edit_id=<?php print($row['id']); ?>"><i class="fa fa-user-edit"></i></a>
							<a href="#" data-toggle="modal" data-target="#deleteModal_<?php echo $row['id'];?>">
                  				<i style="color: #a40000;"class="fas fa-trash fa-sm fa-fw mr-2"></i>
                			</a>
							<!-- Delete Modal -->
							<div class="modal fade" id="deleteModal_<?php echo $row['id'];?>" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
							  <div class="modal-dialog" role="document">
							    <div class="modal-content">
							      <div class="modal-header">
							        <h5 class="modal-title" id="exampleModalLabel">Delete User</h5>
							        <button class="close" type="button" data-dismiss="modal" aria-label="Close">
							          <span aria-hidden="true">×</span>
							        </button>
							      </div>
							      <div class="modal-body">Are you sure you want to delete <?php print($row['first_name'] . ' ' . $row['last_name']);?> from the users list?</div>
							      <div class="modal-footer">
							        <button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
									<form action="api/users/delete.php" method="post">
									<input type="submit" class="btn btn-danger" name="Delete_User[<?php echo $row['id'];?>]" value="Delete" />
									</form>
							      </div>
							    </div>
							  </div>
							</div>							
						</td>
					</tr>
					<?php } ?>			  
                </table>
              </div>
            </div>
          </div>

        </div>
        <!-- /.container-fluid -->

      </div>
      <!-- End of Main Content -->

	  
	  <?php include('nav/footer.php'); ?>

</html>

what is the best way to say if the current session user is logged in, you cannot delete the user. I prefer the delete icon stay in the column unless it would be silly to keep it there.

Firstly, replace the delete icon link with a lock icon for the logged in user.

In the code, compare the logged in users session id with the delete id and handle how you want if they match. The only way that code should even be reached is if someone fudged the URL parameters or submitted the request from some way other than your form/links.

The user id and the session id are identical. It is coded to where the session id is the user id.

What do you mean?

Would an if statement accomplish this?:

if($_SESSION['id'] === $row['id']) {
	echo '<i class="fas fa-lock"></i>';
}

I mean, if there is no direct delete option, because you replaced the delete button with a lock with no link, the only way a request could be submitted with the logged in users id is if someone hacked the url or post parameter or used some other way to submit a request outside of your app.

So this would work then?

if($_SESSION['id'] === $row['id']) {
	echo '<i class="fas fa-lock"></i>';
}

Try it.

By the way, you could eliminate a chunk of code by getting the Role and Active text from the DB with an if query for the active text and pulling from a lookup table for the role text.

Actually, the statement really needs to be:

if($_SESSION['id'] !=== $row['id']) {

because of the code that follows:

<a href="#" data-toggle="modal" data-target="#deleteModal_<?php echo $row['id'];?>">
       <i style="color: #a40000;"class="fas fa-trash fa-sm fa-fw mr-2"></i>
</a>

but is it !== or !=== and what’s the difference in the two?

https://www.php.net/manual/en/language.operators.comparison.php

1 Like

I figured it out. It’s double. Here is the finished product:

<?php if($_SESSION['id'] !== $row['id']) { ?>
<a href="#" data-toggle="modal" data-target="#deleteModal_<?php echo $row['id'];?>">                  				<i style="color: #a40000;"class="fas fa-trash fa-sm fa-fw mr-2"></i> 
</a>
<?php } else { ?>
<i style="color: #808080;"class="fas fa-lock fa-sm fa-fw mr-2"></i>
<?php } ?>

It’s minor, but I would suggest you get in the habit of coding to truth instead of false. Just switch that code around and check for truth. (===)

An if construct is a truthy check by default. It just makes more sense to say “If this is true, do something” rather than say “If it’s true this is false, do something.”