1

I am trying to redirect user on die() to a different place. Like for example if user hits cancel he will be redirected to say tryagain.php or if he enters incorrect credentials he will be redirected to resetpassword.php

Please guide me so that I can achieve that.

How do I achieve that. Here's my code below:

<?php
$realm = 'Restricted area';

//user => password
$users = array('admin' => 'mypass', 'guest' => 'guest');


if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Digest realm="'.$realm.
           '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');

    die('Text to send if user hits Cancel button');
}


// analyze the PHP_AUTH_DIGEST variable
if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
    !isset($users[$data['username']]))
    die('Wrong Credentials!');


// generate the valid response
$A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

if ($data['response'] != $valid_response)
    die('Wrong Credentials!');

// ok, valid username & password
echo 'You are logged in as: ' . $data['username'];


// function to parse the http auth header
function http_digest_parse($txt)
{
    // protect against missing data
    $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
    $data = array();
    $keys = implode('|', array_keys($needed_parts));

    preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);

    foreach ($matches as $m) {
        $data[$m[1]] = $m[3] ? $m[3] : $m[4];
        unset($needed_parts[$m[1]]);
    }

    return $needed_parts ? false : $data;
}
?>
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Rick Cresci
  • 81
  • 1
  • 1
  • 6
  • I'm not sure this is the best approach. If they hit "cancel" why would you serve them a page to "try again"? Cancel is surely not wanting to try again? If wrong credentials then tell them and let them enter the data again. Don't redirect to reset password, that should just be a link and their choice to click it. Just my opinion, although it's also others' if you use KISS https://en.wikipedia.org/wiki/KISS_principle – James Aug 14 '18 at 17:50
  • Something very easily testable. – Jay Blanchard Aug 14 '18 at 17:52
  • What's the `?>` I don't use these anymore. It should be noted when doing a header redirect any output before calling header will prevent it from working that includes `\s ` on a previous page Do you see the space before the php tag (it dosen't let you put spaces in after the backtic for in line code), that is technically output as is line returns after the closing tag. – ArtisticPhoenix Aug 14 '18 at 18:23

3 Answers3

5

You could do something like this

header("Location: http://example.com/tryagain.php");
die();
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Nick Duncan
  • 829
  • 6
  • 17
  • Would `die();` actually occur? It seems like the page would re-direct before the die statement is reached. – Howard P Aug 14 '18 at 17:24
  • 5
    Your script will continue while it processes the redirect momentarily. It is best practice to put `die()` after a redirect to ensure no other code is run while the redirect is being processed. – Nick Duncan Aug 14 '18 at 17:27
  • It does work nicely. However with wrong credential entered it creates a small problem. If an user hit back button to login again it instantly redirect back to forgetpassword.php – Rick Cresci Aug 14 '18 at 17:32
  • 1
    If you would like to avoid that issue you may have to change the login process to execute asynchronously, I don't think there is a simple way to avoid that. – Howard P Aug 14 '18 at 17:36
  • 2
    @RickCresci That's a different problem to this question. You need to handle how you do this. A failed login should really always show the login page again. It's a bit annoying being told "wrong" on a page that doesn't let me fix the issue and makes me click "back". Additionally, rather than redirect, just show an error message on the same page so they are still on the login form page. – James Aug 14 '18 at 17:36
  • Understood. and thank you for your help. I really appreciate that. – Rick Cresci Aug 14 '18 at 17:42
3

Just use

header('Location: tryagain.php');

in your if statement, and call die afterwards.

Quote from this answer:

If you don't put a die() or exit() after your header('Location: http://something') your script may continue resulting in unexpected behaviour. This may for example result in content being disclosed that you actually wanted to prevent with the redirect (HTTP 301). The aforementioned may not directly be visible for an end user as the browser may not render it (due to the 301). Conclusion, the exit() and die() functions stop the script from continuing.

No Name
  • 612
  • 6
  • 15
0

There is a predefined method by PHP header('Location: tryagain.php'); Just replace die statement with the above statement. You don't need to use die because you are conditional so you can easily redirect your user to try again.php if he inserts wrong details You can do more research on it on Google

Howard P
  • 258
  • 3
  • 19
Raashid Din Dar
  • 298
  • 1
  • 5
  • 14
  • This will redirect the whole page on start! – Rick Cresci Aug 14 '18 at 17:20
  • Then please edit your question and add more information what you want to do – Raashid Din Dar Aug 14 '18 at 17:21
  • Even after edit, it's possible to redirect the user on die, the `header('Location: url-here');` will redirect the whole page on start giving php errors if I use that instead of die(). – Rick Cresci Aug 14 '18 at 17:24
  • I am trying to redirect the user on die(). Meaning if he enters incorrect password or cancels the login screen he will be redirected to a different page where he will get to try to login again or reset the password. – Rick Cresci Aug 14 '18 at 17:26
  • You have another choice. Use header location first. Then call die statement after it – Raashid Din Dar Aug 14 '18 at 17:27
  • 1
    I don't think that's the case Rick. Redirecting on die and using `header` + die achieve the same result functionally. This is assuming that tryagain is a standalone webpage and not to be included – Howard P Aug 14 '18 at 17:27
  • As per your comment he should be able to login again . So why don't you put the links inside the try again.php so the user will know that the he the error has caused and after clicking login link he will be able to login again – Raashid Din Dar Aug 14 '18 at 17:32
  • Tried that too but it comes back to the forgetpassword.php again. This only happens on the wrong credential option. – Rick Cresci Aug 14 '18 at 17:37
  • First and foremost you are confusing me. Will user use forgot.php or login.php – Raashid Din Dar Aug 14 '18 at 17:41
  • You should always call `exit` or `die` after a header redirect. I once seen a header redirect in a loop (crazy). But redirection does not stop the current script from executing which can have un-expected results. – ArtisticPhoenix Aug 14 '18 at 18:21