Jump to content

User management accounts - private page per user....?


Skeleten Neteleks

Recommended Posts

[code]<?php
    // First we check if the username is valid, the condition to do so varies
    // based on your application.  A valid username might be alphanumeric only,
    // or alpha only, and usually they have a length restriction.  It's a good
    // idea to test for that here
    // The value $user_name_is_invalid is a dummy to represent whatever check
    // you might actually make
    if(!$user_name_is_invalid){
      $HadErrors = true; // Not valid, so mark that we had errors
      $Errors[] = "Login name appears to be invalid.";
    }
?>[/code]

If you left the above code intact in the [b]ValidateForm[/b] function I provided, then it will always give you that error.  The reason is the line:
[code]if(!$user_name_is_invalid){[/code]

If you read the comment above that line, you will see I'm advocating checking the format of the username provide by the user in the login form.  For instance, if we know that all usernames are alphanumeric and between 3 and 10 characters in length, then we automatically know that [b]reallylongusername[/b] and [b]crap!@#[/b] are [b]invalid[/b].
The variable I used to represent that test is called $user_name_is_invalid.  I included it as a reminder to you that you should check the format of the data being entered on your forms and not to take it for granted that it is correct.  You can change that variable to an appropriate test (using something like preg_match) or comment out that block entirely, depending on how thorough you want to be.

The exact reason your form is always giving you an error is that $user_name_is_invalid is unset, so the expression !$user_name_is_invalid evaluates as true, so the form always thinks there is an error.

The morale of the story here is you can't ever just copy and paste code that is given to you or that you find on the internet and expect it to work.  Look at it in detail, plug some echo "im at this point in the code" statements in various places, and play with it.

That is the only way you can truly learn and understand this stuff.
Link to comment
Share on other sites

  • Replies 50
  • Created
  • Last Reply

Top Posters In This Topic

That's a fair point, but I don't have a background in PHP or programming so I didn't know that leaving it in there was going to cause me this problem.

I have since commented it out...

[code]// if(!$user_name_is_invalid){
    // $HadErrors = true; // Not valid, so mark that we had errors
    //  $Errors[] = "Login name appears to be invalid.";
    // }[/code]

...I still get "Your account could not be found." though. I'm missing something else aren't I!

I changed the UserTable bit to Users (as below - the table name of the users in my DB is called "Users"):

[code]$sql = "SELECT COUNT(*) AS Num FROM Users WHERE "[/code]

...I still get "Your account could not be found."

I'll keep looking through the code, hopefully something will look out of place...

I appreciate if you don't want to help me anymore, and I wish I didn't have to ask obvious questions which I'm sure annoy you!

Many thanks for your help, roopurt. You're a star!
Link to comment
Share on other sites

Ok, so I changed all instances of the word "User" into "Username" in both index.php and home.php to hopefully correspond with the field "Username" in my "Users" table on my database.

I can now successfully reach the home.php page, but I get this error:

Parse error: syntax error, unexpected '.' in /usr/local/psa/home/vhosts/adkm.34sp.com/httpdocs/test95/home.php on line 31

Line 31 (in Windows Notepad) contains this:

[code]. "<p>Description: " . $row['Description'];[/code]

Since this was given to me in your previous code, I assume that it should work.

The full code I now have for the home.php is as follows:

[code]<?php
  // home.php
  // This is our homepage for users

  session_start(); // The first think we must do is start our session

  $Out = ''; // This variable is going to hold our final output for the page

  // First check if we have a valid user
  if(!isset($_SESSION['LoggedIn']) || $_SESSION['LoggedIn'] !== true){
    // Invalid user is trying to hack our site!
    $Out .= 'You do not have permission to view this page.';
  }else{
    // User is valid - print welcome message
    $Out .= "Welcome, {$_SESSION['Username']}!";

    // THIS IS WHERE YOU'D PULL MORE INFORMATION FROM THE DATABASE DEPENDING
    // ON WHICH USER HAS LOGGED IN AND DISPLAY IT TO THEM!
    $sql = "SELECT * FROM Users u, Products p, UserProductLinks l WHERE "
    . "l.username_id = u.id AND "
    . "l.product_id=p.id AND "
    . "u.Username={$_SESSION['UsernameClean']}"; // Notice the added condition here!
$result = mysql_query($sql) or die(mysql_error());

// YOU STILL NEED TO LOOP OVER THE $result
// store the record of the "example" table into $row
while($row = mysql_fetch_array( $result )){ // <- there was a semicolon there,
                                            // which can be removed.  I guess
                                            // I fat-fingered something :D
  $Out .= "<p>Product Name: " . $row['Name'];
      . "<p>Description: " . $row['Description'];
}

    // Let's also print out some debugging information
    $Out .= '<pre style="text-align: left;">' . print_r($_SESSION, true)
          . '</pre>';
  }

  echo $Out;
?>[/code]

I appreciate if you don't wanna carry on teaching dummies like me. I hope I got the correct line 31... I just counted down from the ?php bit.
Link to comment
Share on other sites

[code]<?php
  $Out .= "<p>Product Name: " . $row['Name'];
      . "<p>Description: " . $row['Description'];
?>[/code]

Anytime you receive a programming error on line [i]x[/i], there is a very good chance it's not actually on line [i]x[/i] but some where near it.  If you look at line 30 you will notice it ends in a semi-colon, which terminates a statement.  This causes the beginning [b]dot[/b] on line 31 to cause an error.
Link to comment
Share on other sites

Ok, I removed that, then I got errors from the home.php about not be able to connect to the database, so I added that info in the script at the top:

[code]<?php
  // home.php
  // This is our homepage for users
  mysql_connect("myhost", "dbusername", "dbpassword") or die(mysql_error());
  mysql_select_db("dbname") or die(mysql_error());
  session_start(); // The first think we must do is start our session[/code]

Now all I get is:

[quote]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1"[/quote]

Am I using correct code and it's just my server can't handle it, or am I using incorrect code?
Link to comment
Share on other sites

index.php
[code]<?php
  // index.php
  // A sample PHP script to display a login form and validate user identity
  // Upon successful login, we redirect to our universal home.php
  // I will wrap up functionalities specific to your application in functions
  // which you can fill out for yourself
  mysql_connect("myhost", "dbusername", "dbpassword") or die(mysql_error());
  mysql_select_db("dbname") or die(mysql_error());
  session_start(); // The first think we must do is start our session

  $Out = ''; // This variable is going to hold our final output for the page
  $Errors = Array(); // This is our errors array for the form

  // Now we check in $_SESSION if the user is already logged in
  if(isset($_SESSION['LoggedIn']) && $_SESSION['LoggedIn'] === true){
    // This user is already logged in, we should just redirect to home.php
    header("Location: home.php");
    exit();
  }

  // We're going to count how many entries are in $_POST, if there are _any_
  // entries in $_POST, then our login form must have been submitted and we
  // need to validate the user
  if(count($_POST)){
    // Form has been submitted, we need to validate our user
    if(ValidateForm()){
      // Our user is a valid user, so let's log them in and redirect
      $_SESSION['LoggedIn'] = true;
      $_SESSION['UsernameClean'] = CleanFormField($_POST['Username']);
      $_SESSION['Username'] = $_POST['Username'];
      // We have set our $_SESSION parameters, so now we can redirect
      header("Location: home.php");
      exit();
    }else{
      // Our form was submitted but it's invalid!  This means we need to
      // redisplay the form
      $Out .= ShowForm();
    }
  }else{
    // Form not submitted, we need to show it
    $Out .= ShowForm();
  }

  echo $Out; // Dump our output at the very end

  // ShowForm
  // RETURN: The html to display for the form
  function ShowForm(){
    $Form = ''; // Start with an empty variable

    // First we check for errors
    global $Errors;
    if(count($Errors)){
      // We have errors
      $Form .= 'The follow error(s) were encountered:'
            . '<ul><li>' . implode('</li><li>', $Errors) . '</li><ul>';
    }

    // Set up default values for our form, using the ones from the previous
    // submission if one was made
    $defUsername = isset($_POST['Username']) ? $_POST['Username'] : NULL;

    // Now display the form - we use the post method so that we can use
    // the $_POST array above
    $Form .= '<form name="login" method="post" action="">'
          // Create the login field, using the default
          . 'Login: <input type="text" name="Username" value="' . $defUsername . '" />'
          . '&nbsp;'
          // Create the password field, never set a default password
          . 'Password: <input type="password" name="Password" value="" />'
          . '<input type="submit" name="login" value="Login" />'
          . '</form>';

    // Return our form
    return $Form;
  }

  // ValidateForm
  // This function validates the log in form
  // RETURN: true if form is valid, false otherwise
  function ValidateForm(){
    global $Errors; // We need access to our errors array
    $HadErrors = false; // We initially assume our form is valid

    // We are going to systematically check our field for good data
    // Any time we find bad data, we set $HadErrors to true and add an error
    // message to our $Errors array

    // First we check if the username is valid, the condition to do so varies
    // based on your application.  A valid username might be alphanumeric only,
    // or alpha only, and usually they have a length restriction.  It's a good
    // idea to test for that here
    // The value $user_name_is_invalid is a dummy to represent whatever check
    // you might actually make
    // if(!$user_name_is_invalid){
    // $HadErrors = true; // Not valid, so mark that we had errors
    //  $Errors[] = "Login name appears to be invalid.";
    // }

    // Now we'll check that the user exists in our database, we make sure to
    // clean each of the form fields (User & Password)
    $Clean['Username'] = CleanFormField($_POST['Username']);
    $Clean['PW'] = CleanFormField($_POST['Password']);
    $sql = "SELECT COUNT(*) AS Num FROM Users WHERE "
        . "Username=" . $Clean['Username'] . " AND "
        . "Password=" . $Clean['PW'];
    $q = mysql_query($sql);
    $HaveUsername = false; // Initially we have no user
    if($q){
      // Query successful, let's make sure we have a user
      while($row = mysql_fetch_array($q)){
        $HaveUsername = $row['Num'] == 1; // Set $HaveUsername to the result of the test
        break;
      }
    }
    // By now $HaveUser is true or false depending on if we have a user
    if(!$HaveUsername){
      // We have no user
      $HadErrors = true; // Not valid, so mark that we had errors
      $Errors[] = "Your account could not be found.";
      // It is very important that when checking an account that you NEVER
      // tell the user which of the fields is correct or incorrect.
      // This makes it harder for an attacker to determine if the login
      // or password they are working with are correct or not
    }

    // Now we return the NOT of $HadErrors
    return !$HadErrors;
  }

  // CleanFormField
  // $fld - the input field to clean
  // RETURN: $fld cleaned for safe use
  function CleanFormField($fld){
    if(is_string($fld)){
      // $fld is a string so we must enclose in single quotes and escape
      // special characters
      $fld = "'" . addslashes($fld) . "'";
    }else if(!is_numeric($fld)){
      // We already knew it wasn't a string, but now we know it's not numeric
      // either, so trash it
      $fld = NULL;
    }
    return $fld;
  }
?>[/code]

home.php
[code]<?php
  // home.php
  // This is our homepage for users
  mysql_connect("myhost", "dbusername", "dbpassword") or die(mysql_error());
  mysql_select_db("dbname") or die(mysql_error());  session_start(); // The first think we must do is start our session

  $Out = ''; // This variable is going to hold our final output for the page

  // First check if we have a valid user
  if(!isset($_SESSION['LoggedIn']) || $_SESSION['LoggedIn'] !== true){
    // Invalid user is trying to hack our site!
    $Out .= 'You do not have permission to view this page.';
  }else{
    // User is valid - print welcome message
    $Out .= "Welcome, {$_SESSION['User']}!";

    // THIS IS WHERE YOU'D PULL MORE INFORMATION FROM THE DATABASE DEPENDING
    // ON WHICH USER HAS LOGGED IN AND DISPLAY IT TO THEM!
  $sql = "SELECT * FROM Users u, Products p, UserProductLinks l WHERE "
    . "l.user_id = u.id AND "
    . "l.product_id=p.id AND "
    . "u.User={$_SESSION['UserClean']}"; // Notice the added condition here!
$result = mysql_query($sql) or die(mysql_error());

// YOU STILL NEED TO LOOP OVER THE $result
// store the record of the "example" table into $row
while($row = mysql_fetch_array( $result )){ // <- there was a semicolon there,
                                            // which can be removed.  I guess
                                            // I fat-fingered something :D
  $Out .= "<p>Product Name: " . $row['Name']
        . "<p>Description: " . $row['Description'];
}

    // Let's also print out some debugging information
    $Out .= '<pre style="text-align: left;">' . print_r($_SESSION, true)
          . '</pre>';
  }

  echo $Out;
?>[/code]

thanks
Link to comment
Share on other sites

[code]<?php
  // THIS IS WHERE YOU'D PULL MORE INFORMATION FROM THE DATABASE DEPENDING
    // ON WHICH USER HAS LOGGED IN AND DISPLAY IT TO THEM!
  $sql = "SELECT * FROM Users u, Products p, UserProductLinks l WHERE "
    . "l.user_id = u.id AND "
    . "l.product_id=p.id AND "
    . "u.User={$_SESSION['UserClean']}"; // Notice the added condition here!
?>[/code]

You changed [b]$_SESSION['UserClean'][/b] to [b]$_SESSION['UsernameClean'][/b] in index.php.  You have to change it in home.php as well.
Link to comment
Share on other sites

I try to sign in on http://www.adkm.34sp.com/test95/index.php - I enter the username John123 and the password 1111.

I am then taken to home.php which displays this error message:

[quote]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1[/quote]

I have no way to determine if it's a PHP or MySQL error. I am simply editing these files in Notepad, saving them as PHP files and uploading them to my server.
Link to comment
Share on other sites

If you are writing all of your queries like this:
[code]<?php
$sql = "QUERY IS IN HERE";
$var = mysql_query($sql);
?>[/code]


Insert this line between the assignment to $sql and the function call:
[code]<?php
echo '<pre style="text-align: left;">' . wordwrap(print_r($sql, true), 80) . '</pre>';
?>[/code]

Looks like one of your sql calls is a bad query.  Copy and paste the output here after having done that.
Link to comment
Share on other sites

I have not done what you advised above because I looked through the code before I checked back on this thread.

In the home.php, I changed...

[code]. "u.User={$_SESSION['UserClean']}"; // Notice the added condition here![/code]

to...

[code]. "u.Username={$_SESSION['UsernameClean']}"; // Notice the added condition here![/code]

I thought I had already changed all instances of "User" to "Username" but obviously not. I don't know how I missed it, I pressed F3 to find next through the whole Notepad file from top to bottom.

Anyhow, I now have partial success. The following is what I get when I log in:

[quote]Welcome, John123!
Product Name: Benji's Smokes

Description: Increase the toxicity of your street cred by puffing on these fine fellows. It's a murderous product, which will leave you dying in agnony in maybe 80 years or so. this is product 3 by the way

Array
(
    [LoggedIn] => 1
    [UsernameClean] => 'John123'
    [Username] => John123
)

[/quote]

For some reason it's printing the array code after the details. Unless that's what this section is for?

[code]// Let's also print out some debugging information
    $Out .= '<pre style="text-align: left;">' . print_r($_SESSION, true)
          . '</pre>';[/code]
Link to comment
Share on other sites

The array that is printing is what's currently stored in the $_SESSION auto-global.  I added that to illustrate that information from one page can transparently (as far as the user is concerned) carry over to another page.  Notice that each index of that array is a value that was stored in index.php.

There are many cases where you need to pass information from one script to another and there are several ways you can do so:

1) Using a form with method="post" or method="get"

2) Creating a link that sets URL parameters: home.php?user=john123&logged_in=true

3) With cookies

4) With sessions

I use a combination of forms, urls with parameters, and sessions myself.

In my sessions I store the least amount of information necessary to identify the current user.  Typically this means just a username.  On every page visited in my site, I use the information stored in $_SESSION to look up everything else I need from the database for that specific page.

I use forms for more complicated requests such as site searches, file uploads, message board posts, etc.

I use URL parameters for more simple requests such as sorting a table, pagination, and some types of filtering.

There is no right or wrong way to go about any of this, it's all a matter of preference.  Let's say your users have a lot of information in the DB such as their phone number, address, etc.  You could load all of that information once when they log in, store it all in the $_SESSION array, and never have to access the database again.  As I said, I myself prefer to store the least amount of information necessary because based on just the username I can look that information up again when necessary.  My method adds a little more overhead to the DB but I feel it is more secure as there is less data floating around.

Whatever you choose is a matter of preference and convenience and over time you will develop a way of doing things that you are comfortable with.
Link to comment
Share on other sites

Always a pleasure to help someone eager to learn.  This is the foundation required to program generic pages that appear tailored to specific users.  Keep in mind that as you program, many pieces of your code will require repeated functionality.  When and if you find yourself retyping the same code as you did somewhere else, find a way to make it available from a central location.  This type of programming is less typing for you, easier to maintain and debug, and in general more pleasant to look at 6 months later.

In my opinion, the best programmers are a cross-breed between lazy and hard-working.  You should always spend a sufficient amount of time designing your software and thinking about the many ways in which it will be used; this is the hard-working part of our job.  The design that you come up with should enable you to implement the most common features of your project in the shortest amount of time when you need them; this is the part where we get to be lazy!
Link to comment
Share on other sites

Erm... how would one go about configuring the pages to look like all the others on my website? I have experimented in adding my page template code into the script in index.php but with no luck - I get the PHP code display on the page in a chunk.

My code needs to use both speech marks and apostrophies (some javascript involved).

thanks
Link to comment
Share on other sites

You typically create a template HTML file.  This file holds the general page layout for all of your pages.  Typically there is a string {CONTENT} that you replace with what actually appears on the page.

[b]template.html[/b]
[code]
<!-- template.html - our template file !-->
<html>
  <head>
  </head>
  <body>
    {CONTENT}
  </body>
</html>
[/code]

[b]page.php[/b]
[code]<?php
// page.php - any page within our site

// Build a bunch of content, storing it in $content
// Now we are ready to display it
$file = file_get_contents('template.html');
$file = str_replace('{CONTENT}', $content, $file);
echo $file;
?>[/code]
Link to comment
Share on other sites

Your site is recognizing users by what's in the $_SESSION array.

[b]logout.php[/b]
[code]<?php
  // logout.php
  // log a user out
  session_start();
  session_destroy();
  session_unset();
  $_SESSION = Array();
  header("Location: index.php");
  exit();
?>[/code]
Link to comment
Share on other sites

I also need to add links to some of the word document files that are on the server. I figure I can put the links in the "Description" box on my database?

At the moment, anyone can download the word documents if they explore the diretcories of my site.

Is there any way to use php to password protect the word document files so that only the clients on the database can access them for download?

I will use Word's password feature in the meantime, but I don't know how secure that will be...

I tried googling this but I kept getting mistaken results and it's just frustrating!!!
Link to comment
Share on other sites

You can stop users from browsing directories on the site by turning off automatic indexing for that directory, either by editing httpd.conf and restarting the apache server or by putting a .htaccess file in the directory.

That will only stop people from browsing directories AFAIK however, I don't believe it will stop them from accessing a document if they have the direct URL (AKA path AND filename).

To do that you might have to configure, either through httpd.conf or an .htaccess file, the webserver to not serve those types of files at all.  Instead you'd need to write a script that takes some identifier unique to a file, which then opens the file, sets header information, and directly passes through the contents of the file.  I believe that would be the only way to truly secure files but still have them be servable.

This is an area not well known to me, so this information is in the general ballpark at best.  Perhaps someone with more experience will post eventually!
Link to comment
Share on other sites

I'll settle for passwording in Word for now!

Another question (tell me if I'm asking for too much)... I will at some point be writing up a rather large form, preferrably in HTML so I don't get muddled up in PHP code.

The form should post to a PHP file which:

1. Sends the user a html email which contains the form values, and...
2. Sends the user to a html page generated by the same code used for the email message

Feel free to tell me to bugger off at any point!

thanks
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.