PHP - Secure Member-Only Pages with a Login System

PHP - Secure member-only pages with a login system

I suggest that you change your approach.

Although at first glance these example files looks like a lot, once you study them you'll see it's really much more simple and logical approach than the direction you are now headed.

First, move the db connect / login stuff into a separate file, and require or include that file at top of each PHP page:

INIT.PHP


    // Create connection
$conn = new mysqli($servername, $username, $password, $db);

// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}

//Might as well also load your functions page here, so they are always available
require_once('fn/functions.php');
?>

Now, see how we use it on the Index (and Restricted) pages?

INDEX.PHP

<?php
require_once('inc/head.inc.php');
require_once('fn/init.php');
?>

<body>
<!-- Examples need jQuery, so load that... -->
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<!-- and our own file we will create next... -->
<script type="text/javascript" src="js/index.js"></script>

<div id="pageWrap">
<div id="loginDIV">
LoginID: <input type="text" id="liID" /><br>
LoginPW: <input type="password" id="liPW" /><br>
<input type="button" id="myButt" value="Login" />
</div>
</div>

JS/INDEX.JS

$(function(){
$('#myButt').click(function(){
var id = $('#liID').val();
var pw = $('#liPW').val();
$.ajax({
type: 'post',
url: 'ajax/login.php',
data: 'id=' +id+ '&pw=' +pw,
success: function(d){
if (d.length) alert(d);
if (d==1) {
window.location.href = 'restricted_page.php';
}else{
$('#liID').val('');
$('#liPW').val('');
alert('Please try logging in again');
}
}
});
});//END myButt.click

}); //END document.ready

AJAX/LOGIN.PHP

<?php
$id = $_POST['id'];
$pw = $_POST['pw'];

//Verify from database that ID and PW are okay
//Note that you also should sanitize the data received from user

if ( id and password authenticate ){
//Use database lookups ot get this data: $un = `username`

//Use PHP sessions to set global variable values
$_SESSION['username'] = $un;
echo 1;
}else{
echo 'FAIL';
}

RESTRICTED_PAGE.PHP

<?php
if (!isset($_SESSION['username']) ){
header('Location: ' .'index.php');
}

require_once('inc/head.inc.php');
require_once('fn/init.php');
?>
<body>
<h1>Welcome to the Admin Page, <?php echo $_SESSION['username']; ?>
<!-- AND here go all teh restricted things you need a login to do. -->

More about AJAX - study the simple examples

Members only section for a website

Well, you have several options. Only a few are good.

Since you just stored $myusername in a session variable, you can reference that on members_area.php:

session_start(); // Don't forget this on each page that uses sessions
$myusername = $_SESSION["valid_user"];

That would be the more secure way, given what you've suggested here. Other options involve passing the value with a query string in the URL:

header("Location: members_area.php?user=$myusername");

But this isn't secure and is quite subject to folly. Just FYI it can be done.

However, as a side-note, I might suggest you store a unique identifier (UID or GUID) for each user. It's just a number that only that user has which uniquely identifies it. You'll find it is more robust.

What is the best practice for restricting specific pages to logged in users only in Codeigniter?

You've hit the nail on the head, but there's a slightly more efficient way to do it.

Extend the base controllers, one way (i believe originally outlined by Phil Sturgeon) but I'll summarise here:

See this article for a very indepth write up.

but in essence:

<?php
class MY_Controller extends Controller
{
function __construct()
{
parent::Controller();
if (! $this->session->userdata('first_name'))
{
redirect('login'); // the user is not logged in, redirect them!
}
}
}

so now if you want to restrict access, simply:

class Secret_page extends MY_Controller {

// your logged in specific controller code
}

and the extended controller will automatically check if the user is logged in in the constructor.

as for how, I'd probably set the user_id as the value to check if its set, or perhaps a user "group" - then you can get user permissions and varying levels of access in your system.

hope this helps a little.

edit

Add this to application/config.php

/*
| -------------------------------------------------------------------
| Native Auto-load
| -------------------------------------------------------------------
|
| Nothing to do with cnfig/autoload.php, this allows PHP autoload to work
| for base controllers and some third-party libraries.
|
*/
function __autoload($class)
{
if(strpos($class, 'CI_') !== 0)
{
@include_once( APPPATH . 'core/'. $class . EXT );
}
}

As you are using CI 2.0, you will need to place the MY_Controllers inside Application/CORE rather than Libraries.

My Application/Core Looks a little like:

Admin_Controller.php
MY_Controller.php
Public_Controller.php

How to make an page only accessible when logged in PHP

Add this at the top of Member_area.php:

session_start();
if(!isset($_SESSION['username'])){
header("Location:Login.php");
}

It checks whether the session is set or not, if not it will redirect the user to login page.

Page can only be seen by members with a certain rank

What you are looking for is an ACL (access control list) probably combined with authentication. An ACL will allow you to specify which resources a user with specific credentials has access to.

I have located a few tutorials, but this is not for the faint of heart.

  • http://phpmaster.com/role-based-access-control-in-php/
  • http://blog.davidjclarke.co.uk/database-driven-zend-acl-tutorial-part-one.html
  • http://www.developer.com/lang/php/creating-a-custom-acl-in-php.html

and maybe you could use a class from phpclasses to get you started:

PHPClasses ACL search result

Also as far as I know all of the popular frameworks have ACL and Authentication resources. (Zend Framework, Symfony, CakePHP).

Good luck!



Related Topics



Leave a reply



Submit