1

I need to redirect the user to the page they came from once they've successfully done one of two things: 1) Entering their Invitation Code, or 2) Logged in.

I am trying to apply the answer posted here, but after spending several hours unsuccessfully trying to get it to work I realized it was time to ask for help.

In order to pare down the code, I have only included the snippets relating to Option 1 (Invitation Code). Additionally, in an effort to first get it working with a simpler version (and to more closely replicate the example given), I have temporarily removed the iframes from these pages.

Code Adding

auth_invite_launch.php

//CODE #1
header("Location:sign_in.php?location=".urlencode($_SERVER['REQUEST_URI']));
$redirect = NULL;
if ($_POST['location'] != '') {
    $redirect = $_POST['location'];
}

sign_in.php

//CODE #2
echo '<input type="hidden" name="location" value="';
if (isset($_GET['location'])) {
    echo htmlspecialchars($_GET['location']);
}
echo '" />';

invite_code - exec.php (sign_in.php is submitted here)

//CODE #3
if ($redirect)) {
    header("Location:".$redirect);
}

Pre-existing Code

createaccount.php

require_once('config/auth_invite_launch.php'); // session_start & checks if authorized
is_user_auth(); // Checks if authorized
is_user_logged(); // Checks if logged in 
get_logged_user_id();
if (is_user_logged() == TRUE) {
    $logged_in = true;
    $user_id = $_SESSION['SESS_USER_ID'];
}

auth_invite_launch.php

function is_user_auth(){
  // Checks if logged in to Member Account or has valid Invite Code
  if (isset($_SESSION['SESS_USER_ID']) || isset($_SESSION['TEMP_INVITE_ID'])){
      return true; 
  }
  //Replaced by CODE #1
  header("location: sign_in.php"); // Redirects if not authorized user
}
// Checks if logged in to member account 
function is_user_logged(){
 if ( isset($_SESSION['SESS_USER_ID']) ){
      return true; 
   }
      return false;
}
// Retrieves ID if logged in to member account, NULL otherwise
function get_logged_user_id(){
   if ( is_user_logged() === TRUE ){
      return $_SESSION['SESS_USER_ID'];
   }
       return null;
}

invite_code - exec.php(sign_in.php is submitted here)

// PRECEDED BY statement to fetch matching invite codes from db
if ($stmt - > rowCount() == 1) {
    $invite = $stmt - > fetch();
    $_SESSION['TEMP_INVITE_ID'] = $invite['idinvite_codes'];
    $_SESSION['TEMP_INVITE_CODE'] = $invite['invitation_code'];
    $invite_code = "true";
    //CODE #3 Added here
} else {
    $invite_code = "false";
    header("location: index.php");
    exit();
}
Community
  • 1
  • 1
Chaya Cooper
  • 2,566
  • 2
  • 38
  • 67
  • 1
    My first observation is that you sometimes do a `Location` redirect (e.g. in `auth_invite_launch.php`) without an immediate `exit()`. PHP does not know that a location header should terminate the script, so will merrily keep on going until it detects the remote side has disconnected. Since there is a delay between issuing the header and the disconnect (depending on the speed of the network connection) a seemingly random amount of the script after the header may be executed, and it can give rise to some really awkward bugs. Fix this first `:-)`. – halfer May 03 '15 at 20:24
  • @halfer Done :-) But, as I inferred from your post, that didn't fix it entirely ;-) – Chaya Cooper May 03 '15 at 20:30
  • No, I was hoping it might fix it! though only because the bugs that can cause are seemingly very random. OK, so we might need more detail - you have two actions where you want the user to be redirected back to where they came from, but these do not work. Can you amplify "not working" here? Do they redirect, but not to the right place? Or do they not redirect at all? – halfer May 03 '15 at 20:36
  • 1
    What I would do is (ensuring that all the code is in version control, so you can scrub debug changes easily) add some `echo/exit` pairs in strategic places to trace execution; this will prevent redirects working correctly, but that's okay - you want to see what code gets run. (It's presently not entirely clear what is included in what, and of course readers cannot get debugging, which is how most people would probably approach this issue). – halfer May 03 '15 at 20:36
  • @halfer - At the moment it's not redirecting at all :-( My bad ;-) (goes to show you how many hours I've spent trying to fix this already) – Chaya Cooper May 03 '15 at 20:38
  • OK, for your invitation code redirect, which file do you expect to do the redirect? Does it reach there OK (either by a redirect/GET or a form POST)? Debug based on that question. – halfer May 03 '15 at 21:51
  • @halfer - I know this is totally lame to ask, but can I trouble you to share the specific syntax to use for that? It's been a long time since I've done this ;-) – Chaya Cooper May 03 '15 at 22:45

1 Answers1

1

Your last question in the comments is rather broad: how to trace the execution path in a form-redirect cycle? I'll give it a go.

Let's assume your authorised-only scripts have a login detection device, so that if the user is not logged in, it will redirect to the login system:

if (!isLoggedin())
{
    header('Location: /login.php?location=' . urlencode(getCurrentUrl()));
    exit();
}

So in your login form, you will want a POST action, with a hidden field for the redirect location (it looks like you have this in sign_in.php):

<?php
// Handle post
if ($_POST)
{
    if (loginCorrect())
    {
        // Redirect to the redirect location
        // cleanUrl() should ensure the user input pertains to a
        // local script name, so it cannot be used as a spammer's
        // redirection device
        header('Location: ' . cleanUrl($_POST['redirect']));
        exit();
    }
}
?>
<form method="post">
    <!-- hidden field containing redirect location -->
    <!-- username/password fields -->
</form>

Then you would expect for the URL to get to the redirect location. That's four pages (one repeated):

  • Make a request to a authorised-only page
  • Redirect to login page if not signed in
  • Post either to self or login page handler
  • Redirect to originally requested page, assuming credentials are correct

Each of these can be debugged. Purists will say you should use xDebug and a debugger (controlled from within your IDE) but echo and exit are fine. Just add them at the top of the four pages above, and see if the redirect location (or other variables) are correct:

echo 1;
exit();

Sometimes I will add a few of these to see how control works within a single page. Version control is nearly essential here, since it is important to be able to remove them easily - you obviously don't want to deploy code containing debugging statements.

It's worth using View Source on your login form page too, to ensure the hidden field is correctly populated.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • I'm not sure why I'm having a hard time implementing your beautifully simple instructions :( But the good news is that I was able to figure out what the issue was another way, by using the original code (with iframes) which I knew actually worked - it was just returning the user to index.php after they've logged in and requiring them to click on their desired link again, Since it's still doing the same thing even though I've inserted the new code, it seems that the problem is with the way I'm trying to pass the desired location through – Chaya Cooper May 04 '15 at 01:15
  • Difficult to say @Chaya - I wonder if the iframes thing is confusing things. Everything is on the same domain, right? Iframes pointing to different domains are usually isolated in session terms from the rest of the app. – halfer May 04 '15 at 09:01
  • If there's a redirect to `index.php` then that sounds like there is a redirect feature in the login system that you've not taken into account (maybe you've missed one?). Search for `index.php` in your source code and see if you can find it. Of course, it may think that is what the user wishes to redirect to, in which case there might be a problem with the recording of the hidden field (View Source helps here). – halfer May 04 '15 at 09:03
  • I'm sorry if my code-addled brain interfered with my describing it a bit more clearly :-( The path originates on index.php, so when I use the iframes index.php remains open in the background. The reason why I thought this would help narrow down the issue is because that way I know that it's actually going through the entire process (including returning '$invite_code = "true";' after running the final script on invite_code - exec.php), but since it's not communicating a new location to redirect to, it returns to the same page. – Chaya Cooper May 04 '15 at 15:45
  • Right @Chaya; if `index.php` can accept a query string containing a redirect, but in fact the login/redirect happens in an iframe inside `index.php`, then the outer page won't be touched - the redirect in the iframe is separate. Personally, I'd get rid of the iframe, unless it is critical to your design. They make for disjointed apps, in my view. – halfer May 05 '15 at 15:22