Solved

PHP Login script - go to previous page?

Posted on 2004-10-26
410 Views
Last Modified: 2008-02-01
Hi, I'm creating a login script using PHP and I want it to take the user back to their previous page once they have logged in. How can I do this? with sessions perhaps? Could someone show me the code i need.

thanks.
0
Question by:spikeyjames
    30 Comments
     
    LVL 27

    Expert Comment

    by:Diablo84
    Easiest way is to append the current page to any login links, or if you have a form built into a page append it to the forms action.

    eg.

    <a href="login.php?ref=<?php echo $_SERVER['PHP_SELF']; ?>">Login</a>

    Then on your login page, after you have logged them in and processed the data

    header("location: ".$_GET['ref']);
    exit;

    You could use sessions to do it but this is the simple approach
    0
     
    LVL 3

    Expert Comment

    by:KvdnBerg
    The simplest way would be to use sessions. You check the login and when it's correct you could store his username and the fact that he's logged in into a session variable:

    session_start();
    $_SESSION['username'] = $username;
    $_SESSION['user_logged_in'] = "Y";

    then to redirect you could use

    header("Location:<page address>");

    Assuming you've added a variable and a hidden form field to pass the previous page address, which you could fill in in the header function.

    For authentication purposes you could also use standard packages, such as Pear's Auth: http://pear.php.net/manual/en/package.authentication.php
    0
     
    LVL 27

    Expert Comment

    by:Diablo84
    An example of using sessions, on every page:

    session_start();

    if(isset($_SESSION['cur'])) $_SESSION['prev'] = $_SESSION['cur'];
    $_SESSION['cur'] = $_SERVER['PHP_SELF'];

    This keeps track of the last visited page updating it everytime they access a new page, should be fairly self explanitory.

    Then on your login page aswell as the above code you would also add

    header("location: ".$_SESSION['prev']);
    exit;

    To send them back to the last page after processing the login.
    0
     
    LVL 49

    Assisted Solution

    by:Roonaan
    Well offcourse you could always have this one:

    It uses a hidden field in the form to store the original url the user came from, if it was set.

    :: login.php ::
    <?php
    if($_SERVER['REQUEST_METHOD'] == 'POST')
    {
      $login_ok = false;
      //check login etc//
      ..
      if($login_ok)
      {
        if(!empty($_POST['return_to']))
           header('Location: '. $_POST['return_to']);  //<------------ redirect to return page
        else
           header('Location: index.php');                   //<------------ redirect to default page
        exit();
      }
    }

    /* Show form, because user was not logged in, i.e. not redirected

    $return_to = '/index.php';
    // Try to set $return_to to the referer url.
    if(isset($_SERVER['HTTP_REFERER'])) $return_to = $_SERVER['HTTP_REFERER'];

    //but when this was a failed login attempt, override it with the $_POST['return_to'] field:
    if(isset($_POST['return_to'])) $return_to = $_POST['return_to'];

    //display the form:
    ?>
    <form method="post">
    <input type="hidden" name="return_to" value="<?php echo htmlspecialchars($return_to);?>" />
    <input type="submit" value="Login" />
    </form>

    Regards

    -r-
    0
     
    LVL 27

    Expert Comment

    by:Diablo84
    As KvdnBerg highlighted you could also use the first method i showed using the POST method rather then the GET method (ie. form instead of query string). The end result would be the same, it just means you would echo the current page using $_SERVER['PHP_SELF'] in a hidden field instead of the query string and redirect using $_POST instead of $_GET
    0
     
    LVL 49

    Expert Comment

    by:Roonaan
    Well, if you would echo $_SERVER['PHP_SELF'] into the hidden field, quite obviously you would always be redirecting to login.php itself....

    But then again, my method is somewhat overkill (again :X) to the solution deliverd by Diable84.

    -r-
    0
     
    LVL 27

    Expert Comment

    by:Diablo84
    1) Hence suggesting using the query string in my first post
    2) Hence providing an alternative method using sessions
    3) That is assuming the form is on the same page as the login processor
    4) "Diablo84"
    0
     
    LVL 1

    Author Comment

    by:spikeyjames
    thanks for all the help guys. I still have a problem though:

    The pages are dynamically generated and have variables in the URLs. E.g. index.php?p=test&id=1 etc

    with your methods, $_SERVER['PHP_SELF'] only returns /index.php without the extra parts. How do I get it to include these too?

    BTW, I didn't try Roonaan's code yet, it scares me.
    0
     
    LVL 27

    Assisted Solution

    by:Diablo84
    append

    $_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING'];

    As i recall you also need to add ? so

    $_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING'];
    0
     
    LVL 27

    Expert Comment

    by:Diablo84
    Adding the query string to the query string will more then likely cause you problems though so you might want to consider the sessions method as the easier alternative
    0
     
    LVL 1

    Author Comment

    by:spikeyjames
    ok - we are getting there....
    It works, but only returns the first variable (p=test), and forgets the id=1 bit.
    0
     
    LVL 1

    Author Comment

    by:spikeyjames
    so instead of being: index.php?p=test&id=1
    it's: index.php?p=test
    0
     
    LVL 27

    Expert Comment

    by:Diablo84
    its more then likely reading it as a seperate value, thus is the problem with using the query string with an extra query string, i suppose you could base64_encode it or something similar but it will be easier to use sessions if you need to query string recalled as well.

    To demonstrate the problem your probably seeing, if the url of the page was for example:

    http://localhost/b.php?var=1&var2=2

    If the script contained:

    <a href="login.php?ref=<?php echo $_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']; ?>">Login</a>

    The output would be:

    <a href="login.php?ref=/b.php?var=1&var2=2">Login</a>

    The query string will be seperated by & even though you have intended it to be part of ref so instead of:

    ref => /b.php
    var => 1&var2=2

    You get:

    ref => /b.php?var=1
    var2 => 2
    0
     
    LVL 27

    Expert Comment

    by:Diablo84
    You *could* work around it like this

    <?php echo $_SERVER['QUERY_STRING']."&ref=".$_SERVER['PHP_SELF']; ?>

    eg:

    <a href="login.php?<?php echo $_SERVER['QUERY_STRING']."&ref=".$_SERVER['PHP_SELF']; ?>">Login</a>

    So you first append the current query string to the link and then append the page to it.

    After you handle the login you would then have to build the link again, so again i think it would be easier to store it in a session instead, referring to my previous example something like this should work:

    if(isset($_SESSION['cur'])) $_SESSION['prev'] = $_SESSION['cur'];
    $_SESSION['cur'] = $_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING'];

    Then when it comes to redirecting you will have the url and appended query string available in $_SESSION['prev']
    0
     
    LVL 1

    Author Comment

    by:spikeyjames
    :(

    I tried that, but it doesn't seem to work. Here is the code:

    index.php:

    session_start();
    if(isset($_SESSION['cur'])) $_SESSION['prev'] = $_SESSION['cur'];
    $_SESSION['cur'] = $_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING'];

    that's at the top of the page along with some other php code.

    then the normal login page which is included in index.php:

    <div id="menu">
    <?php if (!isset($_COOKIE['*****_Login']))
    {?>
    <form name="form1" method="POST" action="http://www.*****.com/login.php">
      <br>
        User Name:<br>
        <input name="username" type="text" size="10">
        <br>
        Password:<br>
        <input name="password" type="password" size="10">
        <br>
        <input type="checkbox" name="set" value="ON">Remember Me<br>
        <input type="submit" name="Submit" value="Log In">
      <br>
      <br>
      <br>
    </form>
    <?php } else {?>
    <?php $cookie_info = explode("-", $_COOKIE['*****_Login']);
       $username = $cookie_info[0];
       $password = $cookie_info[1]; echo "Welcome, ".$username."!";?>
    <br>
    <a href="http://www.*****.com/members/index.php?p=usersettings&inc=us&inc=a">Manage Settings</a><br>
    <a href="http://www.*****.com/logout.php">Log out</a><?php }?>
    </div>

    and login.php:

    <?php require_once('Connections/*****.php'); ?>
    <?php
    $username = $_POST['username'];
    $password = md5($_POST['password']);
    mysql_select_db($database_*****, $*****);
    $query_login = "SELECT username, password, subscription_end, subscription_type FROM subscriptions WHERE username = '$username' AND password = '$password'";
    $login = mysql_query($query_login, $*****) or die(mysql_error());
    $row_login = mysql_fetch_assoc($login);
    $totalRows_login = mysql_num_rows($login);
    $time = time();
    $date = date('Y-m-d');
    $sub_end = $row_login['subscription_end'];
    $secdiff = (strtotime($date) - strtotime($expdate));
    if ($totalRows_login == 1)
        { $cookie_data = $username.'-'.$password;  
            if($check=='ON')
            {
                if(setcookie("*****_Login",$cookie_data,$time+2678400,"/",".*****.com",0)==TRUE)
                { if (date($date) > date($sub_end)) {header("Location: http://www.*****.com/index.php?p=expired");} else {
    header("location: ".$_SESSION['prev']);} ?>
                <? }
            } elseif(setcookie("*****_Login",$cookie_data,$time+3600,"/",".*****.com",0)==TRUE)
                { if (date($date) > date($sub_end)) {header("Location: http://www.*****.com/index.php?p=expired");} else {
    header("location: ".$_SESSION['prev']);} ?>
                <? }
    $datetime = date("YmdHis");
    mysql_query("UPDATE subscriptions SET last_login='$datetime' WHERE username='$username'");
    }
        else
        {
    header("Location: http://www.*****.com/index.php?p=denied");
        }
    ?>
    <?php
    mysql_free_result($login);
    ?>
    0
     
    LVL 27

    Expert Comment

    by:Diablo84
    I don't have time to look at your code right now, will do so later if needed, but in the mean time heres a few pointers which will hopefully get to the bottom of it.

    1) check $_SESSION['prev'] is actually set and contains a value by outputting it with echo on your login processing page

    2) include the http protocol in your headers to make sure it finds the page

    eg:

    header("location: http://www.yourdomain.com".$_SESSION['prev']);

    3) As i said at this point i havent time to look through your code but it might be that an extra page during the login, so the previous page is actually being set as login.php so its redirecting to itself, if this is the case i will probably have to help you out later with the problem.

    Best of luck in the mean time.
    0
     
    LVL 20

    Expert Comment

    by:virmaior
    MUCH easier method...

    first, add this to your header file:

    <?php
          session_start();
          if (!($_SESSION["loggedin"] == 'y')) {
                require("login.php");
                exit();
          }
    ...

    add this into the form of login.php:

    printf('<input type="hidden" name="gourl" value="%s">',$_SERVER["REQUEST_URI"]);

    $_SERVER['request_uri'] will equal the page they thought they were loading.  (This works since no matter what page they try to load if the session variable says they aren't logged in then they will see the login page)

    then when you process the form...


    function jumpTo($url) {

    printf('
    <HEAD>
    <SCRIPT language="JavaScript">
    <!--
    window.location="%s";
    //-->
    </SCRIPT>
    </HEAD>',$url);

    }


    if ($_POST['gourl'] <> '') {jumpTo($_POST['gourl']);}  else {jumpTo("index.php");}

    this handles all of it...
    0
     
    LVL 7

    Accepted Solution

    by:
    ... & Easiest ;)

    <?php
    header('Location: ' . $_SERVER['HTTP_REFERER']);
    die;
    ?>

    But sessions are safer, it's obvious.
    Ben
    0
     
    LVL 27

    Expert Comment

    by:Diablo84
    In a perfect world the referer would be reliable, would certainly be convienient. Sadly not though as is the case with most client side factors, its a shame really but understandable. I suppose if you wanted to use the referer you could do so with a conditional as back up, eg (psuedocode): if(!empty(referer)) redirectto referer else redirectto index page. This isnt as reliable and would also experience issues with the referer is forged as xxxxXXXXX etc as some are but an option none the less.

    [Slightly offtopic], a friend of mine once experienced problems with the referer more so then is normal, no users came through with the referer set. To cut a long story short it turned out that Dreamweaver MX has a bug, when typing $_... you get the drop down with the super globals and then the same for the indexes. After clicking $_SERVER and then HTTP_REFERER it writes "$_SERVER['HTTP_REFERRER']" in the document (notice the extra R). So the bottom line is, the referer can be less reliable then usual... when your editor has issues with spelling :)
    0
     
    LVL 1

    Author Comment

    by:spikeyjames
    YAY! header('Location: ' . $_SERVER['HTTP_REFERER']); works!

    What is wrong with using this way?
    0
     
    LVL 49

    Expert Comment

    by:Roonaan
    > I suppose if you wanted to use the referer you could do so with a conditional as back up, eg
    >(psuedocode): if(!empty(referer)) redirectto referer else redirectto index page. This isnt as
    > reliable and would also experience issues with the referer is forged as xxxxXXXXX etc as
    >some are but an option none the less.

    And which is about exactly what my code in my first posting does :^)

    -r-
    0
     
    LVL 1

    Author Comment

    by:spikeyjames
    all of you have helped so much, and spent a lot of time on this...So who do I give the credits to!?

    I want to give them to Diablo84 as he put the most effort into helping me, but in the end BenMorel solves the problem, which turns out to be what Roonaan said in the first place...argh.
    0
     
    LVL 3

    Expert Comment

    by:KvdnBerg
    That's what the assisted answer point splitting thing is for.
    See, I assisted! (just kidding ;-))
    0
     
    LVL 1

    Author Comment

    by:spikeyjames
    Thanks to all of you who helped out!
    0
     
    LVL 27

    Expert Comment

    by:Diablo84
    hi spikeyjames, sorry i did not return sooner havent been able to get back on until now.

    >> What is wrong with using this way?

    Basically its very unreliable as its a client side factor which in some cases will not be set or will be blocked (I believe one of the Norton products blocks it from being sent for example) so really cannot be trusted which is why i always avoid using it and use sessions instead. I was more pointing it out as an option then backing it as a solution, id rather have a more reliable method functioning but if it works for you then thats great.

    The quote from the manual explaining it  a little:

     "The address of the page (if any) which referred the user agent to the current page. This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted."
    0
     
    LVL 1

    Author Comment

    by:spikeyjames
    :S oh dear, so I'm back where i started then. This login script needs to be compatible with everyone, because thousands of people will be using it.
    0
     
    LVL 27

    Expert Comment

    by:Diablo84
    As long as you have an alternative page to redirect to for those who have the referer blocked it shouldn't be too much of a problem. It just means that those who block the referer from being sent will be sent back to the index page (for example) rather then the page they came from. If you use the referer though i would adivse that as well as checking if its empty you also check that its a valid url as some referers are set to things like "XXXX++++++++++++++++++++".
    0
     
    LVL 20

    Expert Comment

    by:virmaior
    the solution I gave you is not affected by this problem
    0
     
    LVL 27

    Expert Comment

    by:Diablo84
    neither are any of the others that don't use the referers...
    0
     
    LVL 20

    Expert Comment

    by:virmaior
    true
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone. Privacy Policy Terms of Use

    Featured Post

    How to improve team productivity

    Quip adds documents, spreadsheets, and tasklists to your Slack experience
    - Elevate ideas to Quip docs
    - Share Quip docs in Slack
    - Get notified of changes to your docs
    - Available on iOS/Android/Desktop/Web
    - Online/Offline

    Suggested Solutions

    The Client Need Led Us to RSS I recently had an investment company ask me how they might notify their constituents about their newsworthy publications.  Probably you would think "Facebook" or "Twitter" but this is an interesting client.  Their cons…
    Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
    Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
    The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

    875 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    15 Experts available now in Live!

    Get 1:1 Help Now