views:

94

answers:

7

Hi all,

I'm new to web programing and im trying to find a few good examples / tutorials on how to do a decent job of creating a website that requires users to log on to view any pages beyond the main log in page.

so far i've found 1 or 2 that ive tried but i keep running into the same problem. If i just enter the url of the page i want to see manually i can get in like there was nothing there.

any suggestions are welcome but please remember i'm pretty new to php and web

+1  A: 

There's HTTP Auth:

http://php.net/manual/en/features.http-auth.php

Or you can roll your own with a login form and session tracking:

http://www.php.net/manual/en/book.session.php.

Http auth means the user gets a pop-up dialog window asking for a username and password, it's less usual than the self-rolled version.

Enjoy!

Robin
A: 

It's not using PHP for the authentication, but you can use htaccess to provide authentication and possibly manage the .htpasswd file using PHP:

http://www.freewebmasterhelp.com/tutorials/htaccess/

Ryan Mentley
he wants php, not apache configuration, don't get off topic
Bob Fincheimer
He stated that he was new to web programming and that he was looking for a way of creating a website that requires users to log on to view any pages beyond the main log in page. .htaccess is one way to do this that he may not have thought of. He never said the solution had to be in PHP.
Ryan Mentley
I still want to do php but this will help me with a diffrent project so +1 for the idea anyway (I don't know who -1ed you)
Crash893
+1  A: 

This is the same as what LordArtemis suggested, but this tutorial is easier to follow and geared towards begginers.

http://css-tricks.com/easily-password-protect-a-website-or-subdirectory/

WillyG
+1  A: 

The sites you mentioned are likely bypassable because the pages past the security check don't save and then check for login status on each page. You need to check that a visitor is logged in before access to a page is granted.

kevtrout
+1  A: 

I think most users would expect form input for a login. If you want the user to come back and log in with the same account later after their session expires, you'd need a database to store user information.

When storing user information in a database, you should probably not actually store their password, either. For an example:

name    password                            ...
-----------------------------------------------
Johnny  '3858f62230ac3c915f300c664312c63f'
Alice   '80338e79d2ca9b9c090ebaaa2ef293c7'
.
.
.

Johnny's password is actually "foobar", but the database stores md5('foobar'). When Johnny tries to log in, he enters his username ('Johnny') and his password ('foobar'). In PHP, you hash the password he entered, and call up his password value from the database, resulting in:

if (md5('foobar') == '3858f62230ac3c915f300c664312c63f')

This conditional is true. You can confirm if he logged in correctly, but you're never storing his actual password.

Alice's password is 'foobaz'. She tries to log in, but accidentally types 'foobar', Johnny's password. this results in:

if(md5('foobar') == '80338e79d2ca9b9c090ebaaa2ef293c7')

Which is false. Again, you don't know what Alice's password is, just that she entered the wrong one.

The downside to this strategy, of course, is that you can't tell the user what their password is when they forget it -- you don't know! You can resolve this by letting a user reset their password (to some semi-random string) instead of strait telling them what their password is.

Brian S
Note that this method would be the best way to go if you had to store individual pieces of information for each user. If you simply only needed certain people to see parts, or an entire website, this may be overkill.
WillyG
+1  A: 

When logging in using a form, you should check the username and password in the database. The password should be scrambled (usually done using the MD5 hash algorithm), and stored in the database in the same way. You capture the variables, using something like (use some validation to check if the POST variables are valid):

$username = $_POST['username'];
$passwordHash = md5( $_POST['password'] );

The username and hashed password should be stored in your database. You can then check for a match in the database using:

$res = mysql_query("SELECT * FROM users WHERE username='".$username."' && password='".$password."'");

When a user is found, you use sessions to store the user values, which will allow you to get access to a users information across pages. NOTE: session_start() is usually placed at the top of the page, but I'll place it here for readability.

if ( mysql_num_rows($res) ) {
  session_start();
  session_regenerate_id(); // regenerate session_id to help prevent session hijacking
  $row = mysql_fetch_assoc($res);
  $_SESSION['logged_on'] = true;
  $_SESSION['username'] = $row['username'];
  // add more session variables about the user as needed
}

On every page you want to protect, you add the following to the top of those pages:

session_start();
if ( !isset($_SESSION['logged_on']) ) {
  header("Location: login.php"); // user is not logged in, redirect to login page
  exit;
}
// page content here
Mads Jensen
+2  A: 

Okay, I'll explain how the basic concept goes and a very simple implementation to get things going.

PHP (and most web applications) rely on RESTful services -- which, to our concern at the moment, means every request is not remotely bound to any other request being made - either that being by the same user or others.

So what does that mean?

This means that for every single request, you need to do your checks. You need to make sure if the user has permissions to execute that page, or less severely even see its contents.

How is this achieved?

By many ways, actually. There are lots of techniques used to enforce authorization on web applications but they would essentially both break down to one of two -- either centralized, or decentralized.

-- Centralized

This means all your actions (and controllers) are being handled through a single file. Say index.php. This file would then include or delegate its tasks to other files (that are not runnable on their own via normal requests) based on request parameters. This is a very popular approach, but not exactly straight forward for new developers. Examples of applications that use this approach would have URLS of the type: index.php?do=register, index.php?do=login, index.php?do=showtopic&topic_id=2, and so forth.

A simple implementation of this technique would go like:

<?php
// index.php
define('RUNNING_APP', true);
// 1. place your auth code here, or...
switch ($_REQUEST['do']) {
    case 'register':
        // 2. or here
        include 'inc/register.php';
        break;

    case 'do_register':
        // 2. and here, and before every include.. and so forth.
        include 'inc/do_register.php';
        break;
}
?>

<?php
// inc/register.php
defined('RUNNING_APP') or die('Cannot access this script directly'); // make sure to break direct access
?>
<form action="index.php?do=do_register">
<!-- form elements -->
</form>

and so forth.

I've documented where the usual auth code should go.

-- Decentralized

Using this approach, however, your auth code should go at the beginning of every single file. URLS of applications of this sort usually look something like: register.php, login.php, and so forth. The main problem here is that you need to perform all auth logic per file, as stated above, and that may be a hectic job if your files increase in amount. A convenient solution is to have that logic in a single file, and include that file (which would kill the request for unauth personel) before any of your logic. A simple example would be:

<?php
// index.php
include('inc/auth.php');
// index logic
?>

<?php
// register.php
include 'inc/auth.php';
// register logic
?>

<?php
// inc/auth.php
$logged_in = false;
if (!$logged_in) {
    die ('You do not have permission to access this page. Please login');
}
?>
msakr