开发者

Clean way to make a php login script on a site with includes?

开发者 https://www.devze.com 2023-02-15 02:55 出处:网络
Basically I have an index.php file with navigation in form of includes only. My script can check whether a user exists by checking a database.

Basically I have an index.php file with navigation in form of includes only.


  • My script can check whether a user exists by checking a database.

  • It can also log you in if the check was successful.

My problem is redirects! Do I really have to use echo "<meta http-equiv=refresh content=\"1; URL=index.php\">";?

And I also have to make tons of if-statements to cover the entire possibilities of a users actions (have to take evil pe开发者_StackOverflowople into account).

Headers are already ruled out because I use includes and requires.

I'm on the brinck of switching to ASP.NET or something rediculous... This scripting is making me mad :P


Sounds like you either need to use an existing content management system or framework or learn to code in a modular drop-in fashion. Coding it for modularity would mean that the included script can be left out and the page still function as usual.

I'll post an example in a bit.

Just looked at your code. The index page is insecure. Do not do it like that. I could do something nasty like index.php?p=../../../whateverfile and try to include it from outside of /inc/. You need some sort of protection against user input. Something like an array specifying valid files to include to check against, or a db table containing valid files to include that it can check against.

edit Also, never ever store the password in a cookie. You should generate a unique key or something for the login and store it and check against it instead of the password.

Here's what you'd want to do: Split the login file up into checking logic and presentation. Once you do that it means that the checking logic can be included anywhere on the page, while the form itself can also be placed anywhere.

Here's a little example:

loginCheck.php

if(isset($_POST['login']))
{

     if(!$_POST['username'] || strlen($_POST['username']) <= 3 || strlen($_POST['username']) >= 20)  //Check user input for validity
     {
          $loginerror['username'] = "Username is required.  Must be between 3 and 20 characters long.";
     }
     if(!$_POST['password'])
     {
          $loginerror['password'] = "Password is required.";
     }


     if(count($loginerror) == 0)
     {     
          $username = mysql_real_escape_string(trim($_POST['username'])); //Do whatever to the user input
          $password = mysql_reql_escape_string(trim($_POST['password']));

          $sql = mysql_query("SELECT `username`,`password`,`etc` FROM `users` WHERE `username` = '$username' AND `password` = '$password' LIMIT 1");  //Select both at the same time

          if(mysql_num_rows($sql) == 0)
          {
               $loginerror['login'] = "Username or Password incorrect or does not exist.";  //It's smart not to let people know which they got wrong.
          }
          else
          {
               $_SESSION['username'] = $username;
               $_SESSION['loggedin'] = true;
               $loginmessage = 'Welcome ' . $username. ', you are successfully logged in';
          }
      }
 }

loginForm.php

function dispError($name,&$errors)
{
     if(isset($errors[$name]))
     {
          return '<span class="error">' . $errors[$name] . '</span>';
     }
     return '';
}

if(isset($loginmessage))
{
     echo $loginmessage;
}
elseif(isset($_SESSION['username']) && isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true)
{
     echo 'Welcome, ' . $_SESSION['username'];
}
else
{
     if(!isset($loginerror) || !is_array($loginerror))
     {
          $loginerror = array();  //Gotta make sure it exists for the next part if it hasn't been set.
     }
     echo dispError('login',$loginerror);
     echo '<form method="post" action="">';
     echo '<input name="username" placeholder="Username..." type="text" maxlength="15" />' . dispError('username',$loginerror) . '<br /><br />';
     echo '<input name="password" placeholder="Password..." type="password" maxlength="20" />' . dispError('password',$loginerror) . '<br /><br />';
     echo '<input name="login" type="submit" value="Login" style="width:100px;">';
     echo '</form>';
}

index.php

if(isset($_POST['login']))
{
     require_once("loginCheck.php");
}

//various other includes and requires

require_once("loginForm.php");

This way there's also no reason to redirect away from the login form/sign in page, as the checks can be easily included inline and both the form and the check can be included on any and all pages dynamically just by dropping it in where necessary.


When you validate the user/login set a session variable

$_SESSION['loggedin'] = true;

Then at the very top of each php file add the following code (You can put this code in a php file and use requires('thiscode.php')

<?php
session_start();

if(!loggedIn())
{
    header('Location: login.php');
    die();
}

function loggedIn()
{
    if($_SESSION['loggedin'])
        return true;
    else
        return false;
}
?>


You can probably still use the header() function, like this: <?php header("Location: login.php"); ?> Make sure to add it before your include()s!

If not, post a snip-it of your code here, then I can analyse it.


Have you tried using ob_start(); // it makes you able to use headers anytime

make sure to put it on the first line and don't forget to add a ob_end_flush(); at the end

for more information : http://ca2.php.net/manual/en/function.ob-start.php


I have an index.php file with navigation in form of includes only.

....

tons of if-statements

If you really must use a front controller architecture then try to at least make it data driven. You're simultaneously building a house of cards and a stick to beat yourself with.

My problem is redirects! Do I really have to use....

No. Only if the rest of your code is a mess and you want to implement a PRG pattern too. And even then it's not necessary.

Headers are already ruled out because I use includes and requires

Eh? That rather implies that your templating system is a mess.

I'm on the brinck of switching to ASP.NET or

It's not going to make you a better programmer.

You've made a lot of conflicting choices about the architecture of your application and now you're finding that these don't all fit together as easily as you had expected.

Go have a look at some of the excellent PHP CMS and frameworks available - and see how they tackle these problems.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号