6

I am new to PHP and am struggling with the following:

I have a page where I want to check if someone is a registered user before letting them see the content of the site. So my thought was that in my header file (which is referenced on all single pages via require_once("includes/header.php");) I can check on that and redirect them to a login page (login.php) if they have not logged yet.

So here is everything that I have in my header:

<!DOCTYPE html>
<html>
    <head>
        <?php 
            define("someUnguessableVariable", "anotherUnguessableVariable");
            session_start();
            if(!(isset($_SESSION['login']) && $_SESSION['login'] != '')){
                header ("Location: login.php");
            }

            include "system/config.php";

            $pageURL = basename($_SERVER["REQUEST_URI"]);
            $pageName = pathinfo(parse_url($pageURL, PHP_URL_PATH), PATHINFO_FILENAME); 

            $selectedLang = $_GET["lang"];
                if(!isset($selectedLang)){
                    $selectedLang = "de";
                }
            $langURL = "?lang=" . $selectedLang;

            $conn = new mysqli($dbServer, $dbUser, $dbPass, $dbName);
            $conn->set_charset("utf8");
            if($conn->connect_error){
                die("Connection failed: " . $conn->connect_error);
            } 
            // fetch main translations
            $location = "%main%";
            $stmt = $conn->prepare("SELECT tID, " . $selectedLang . " FROM TranslationsMain WHERE location LIKE ? ORDER BY tID");
            $stmt->bind_param("s", $location);
            $stmt->execute();
            $result = $stmt->get_result();  
            while($arrTranslations = $result->fetch_assoc()){
                $trans[] = array("ID" => $arrTranslations["tID"], "trans" => $arrTranslations[$selectedLang]);
            }
            $conn->close();

            // get main translations by ID
            function fetchTransMain($trans, $itemID){
                foreach($trans as $key => $val){
                    if($val["ID"] == $itemID){
                        return $val["trans"];
                    }
                }
            }
        ?>

        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta name="author" content="Some author" />
        <meta name="description" content="Created: 2015-06" />

        <base href="http://www.myurl.de" target="_self" />

        <title>Some title</title>

        <!-- CSS -->        
        <link rel="stylesheet" type="text/css" href="includes/styles.css" />
        <!-- CSS - Font Awesome -->
        <link rel="stylesheet" type="text/css" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />

        <!-- include favicon -->
        <link rel="shortcut icon" href="images/favicon/favicon.ico" type="image/x-icon" />
        <link rel="icon" href="images/favicon/favicon.png" type="image/png" />
        <link rel="icon" sizes="32x32" href="images/favicon/favicon-32.png" type="image/png" />
        <link rel="icon" sizes="64x64" href="images/favicon/favicon-64.png" type="image/png" />
        <link rel="icon" sizes="96x96" href="images/favicon/favicon-96.png" type="image/png" />
        <link rel="icon" sizes="196x196" href="images/favicon/favicon-196.png" type="image/png" />
        <link rel="apple-touch-icon" sizes="152x152" href="images/favicon/apple-touch-icon.png" />
        <link rel="apple-touch-icon" sizes="60x60" href="images/favicon/apple-touch-icon-60x60.png" />
        <link rel="apple-touch-icon" sizes="76x76" href="images/favicon/apple-touch-icon-76x76.png" />
        <link rel="apple-touch-icon" sizes="114x114" href="images/favicon/apple-touch-icon-114x114.png" />
        <link rel="apple-touch-icon" sizes="120x120" href="images/favicon/apple-touch-icon-120x120.png" />
        <link rel="apple-touch-icon" sizes="144x144" href="images/favicon/apple-touch-icon-144x144.png" />
        <meta name="msapplication-TileImage" content="favicon-144.png" />
        <meta name="msapplication-TileColor" content="#ffffff" />

        <script>
            var baseURL = '<?php echo $baseURL; ?>';
            var pageURL = '<?php echo $pageURL; ?>';
            var pageName = '<?php echo $pageName; ?>';
            var selectedLang = '<?php echo $selectedLang; ?>';
        </script>
    </head>   
    <body>

Now this is not working and I think I am probably missing a couple of things but I couldn't find a good tutorial or guideline on that. Also, I am not sure if there is anything else I need to do in order to start and set up the session.

Can someone help me with this ?

Note:
This is only about checking if a user is already logged in since all the actual user registration and verification is done on the separate login page and for this I already have the code working.

Update: Enabling error messages returns the following errors:

Warning: session_start(): Cannot send session cookie - headers already sent by (output started at /homepages/21/d580042014/htdocs/index.php:2) in /homepages/21/d580042014/htdocs/includes/header.php on line 9

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /homepages/21/d580042014/htdocs/index.php:2) in /homepages/21/d580042014/htdocs/includes/header.php on line 9
array(0) { } 
Warning: Cannot modify header information - headers already sent by (output started at /homepages/21/d580042014/htdocs/index.php:2) in /homepages/21/d580042014/htdocs/includes/header.php on line 12

Notice: Undefined index: lang in /homepages/21/d580042014/htdocs/includes/header.php on line 18

Update:
As per the comments I now posted everything that's currently in the header.

Many thanks in advance.

TaneMahuta
  • 367
  • 3
  • 8
  • 17

4 Answers4

11

Update: The question has been resolved in chat.


As per your edit, change this block:

<!DOCTYPE html>
<html>
    <head>
        <?php 
            define("someUnguessableVariable", "anotherUnguessableVariable");
            session_start();
            if(!(isset($_SESSION['login']) && $_SESSION['login'] != '')){
                header ("Location: login.php");
            }
        

to:

<?php 
session_start();
?>

<!DOCTYPE html>
<html>
    <head>
        <?php 
            define("someUnguessableVariable", "anotherUnguessableVariable");
            
            if(!isset($_SESSION['login']) && $_SESSION['login'] != ''){
                header ("Location: login.php");
                exit; // stop further executing, very important
            }
  • Follow the same structure for starting the session in all your files using sessions.
  • Make sure that your file does not have a byte order mark (BOM).
  • No space before <?php etc. this has already been established in comments.

Using a code editor such as Notepad++ https://notepad-plus-plus.org/ and to save it as UTF-8 without BOM which will ensure there is no byte order mark.

Also, using the new method for your sessions array check.

if(!isset($_SESSION['login']) && $_SESSION['login'] != ''){

Also check to see that none of your included/required files have the same issues, including login.php.


Footnotes:

Inside Notepad++'s dropdown menu, you will see

  • Encoding. It will show you what the present file's encoding is set to.

If it does show a byte order mark, follow these steps:

  1. Click on "Encoding".
  2. Convert to UTF-8 without BOM
  3. Save the file.
  • Do this for all your files.

Reference(s):


Sidenote:

You should change $stmt->execute(); to

if(!$stmt->execute()){
    trigger_error("there was an error....".$conn->error, E_USER_WARNING);
}
  • It's better to catch possible errors in your query.
Community
  • 1
  • 1
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
  • Thanks so much for this. I am sorry but just changing the code didn't fix it. Will look into yours and Michael's references now and will update the post then. – TaneMahuta Jun 24 '15 at 17:10
  • 1
    @TaneMahuta You're welcome. Now, please define "didn't fix it". Are you still getting the same errors? Or new ones? and have you opened your files to see what the encoding is? – Funk Forty Niner Jun 24 '15 at 17:13
  • Thanks again. It has reduced the errors so there is a partial success. :) Instead of 4 I am now only getting 2: array(0) { } Notice: Undefined index: login in /homepages/21/d580042014/htdocs/includes/header.php on line 13 Notice: Undefined index: lang in /homepages/21/d580042014/htdocs/includes/header.php on line 23 – TaneMahuta Jun 24 '15 at 17:18
  • Update: I fixed the error for line 23 so there is only the one left for line 13 now which is exactly the line to check for the session. – TaneMahuta Jun 24 '15 at 17:19
  • @TaneMahuta then this tells me that the session array hasn't been set. If it isn't set from a previous file, then that will trigger the notice(s). Your GET array also isn't set somewhere. As per your "Update", then check everything, lettercase is important as is the placement. PHP is picky for all that ;-) – Funk Forty Niner Jun 24 '15 at 17:21
  • Ok, just to explain: The error for line 23 was for the line where I check for $selectedLang = $_GET["lang"];. When I added ?lang=... to the url then this got resolved so it seemed to have an issue here if this was not provided at all. – TaneMahuta Jun 24 '15 at 17:22
  • 1
    @TaneMahuta as I mentioned in [a previous comment](http://stackoverflow.com/questions/31031344/php-how-to-check-if-user-is-already-logged-in-and-otherwise-redirect-to-login-p/31032568?noredirect=1#comment50087789_31031344) under your question: *"Assign a session array/variable to the POST array"* from an HTML form you may have; this being for the `Notice: Undefined index: login`. – Funk Forty Niner Jun 24 '15 at 17:23
  • Ok, just one last question, when I start the session do I have to set its name to "login" ? That was my initial thought of how to name the session which is why this is mentioned in the line to check for the session. It looks to me like this is causing the error. – TaneMahuta Jun 24 '15 at 17:26
  • Also, could you help me by explaining "Assign a session array/variable to the POST array" to make sure I do this right ? – TaneMahuta Jun 24 '15 at 17:27
  • @TaneMahuta yes, be consistent in all your pages and sessions arrays. I myself use relative words such as "username" for both POST and SESSION arrays so that I don't get mixed up. An example: `$_SESSION['username'] = $_POST['username'];` and base yourself on that, and using your own array names. This is just an example. Another is `$user = $_POST['user']; $_SESSION['user'] = $user;` – Funk Forty Niner Jun 24 '15 at 17:31
  • Thanks. What I mean is we check if a session with the name login is set but we never give the session a name when we start it, no ? Sorry if I am reading this wrong. – TaneMahuta Jun 24 '15 at 17:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/81447/discussion-between-fred-ii-and-tanemahuta). – Funk Forty Niner Jun 24 '15 at 17:34
  • 1
    This has been resolved through the chat - thanks so much ! – TaneMahuta Jun 24 '15 at 18:20
  • @TaneMahuta You're very much welcome. I was happy to have helped, *cheers!* – Funk Forty Niner Jun 24 '15 at 18:21
  • You have `header ("Location: login.php");` after ` – Onimusha Jun 24 '15 at 18:38
2

You need to move

session_start();
if((!isset($_SESSION['login']) && $_SESSION['login'] != '')){
    header ("Location: login.php");
}

to the top of the scrip and move ! inside the bracket.

petebolduc
  • 1,233
  • 1
  • 13
  • 20
  • Thanks for this - let me check. – TaneMahuta Jun 24 '15 at 16:23
  • Ok, I put this at the very top of the header but it still doesn't redirect. – TaneMahuta Jun 24 '15 at 16:26
  • is the header being called in after another script? – petebolduc Jun 24 '15 at 16:28
  • 1
    the extra `()` brackets are not necessary. `if(!isset($_SESSION['login']) && $_SESSION['login'] != ''){` – Funk Forty Niner Jun 24 '15 at 16:29
  • @petebolduc: Thanks. No, the header is the first thing that is on any page and is included in the first line of each page code. – TaneMahuta Jun 24 '15 at 16:33
  • 1
    @Onimusha is correct... the `!=` needs to be `==` as well... the define can go below... your goal is to test if they are logged in and redirect... `session_start();` should be first. also you can only end headers once... a work around that issue though is `echo ''; ` – petebolduc Jun 24 '15 at 16:44
1

Put the user profile in session variables in PHP script you call after the login page

$_SESSION['user_id'] = $row["user_id"];
$_SESSION['profile_id'] = $row["profile_id"];
$_SESSION['name'] = $row["name"];
$_SESSION['surname'] = $row["surname"];
$_SESSION['application_auth'] = $row["application_auth"];

Put the following code at the top of each page you want to protect by not valid users

<?php 
include("sessionCheck.php");
?>

The sessionCheck script In this case I also check if the user is entitled to view the specific page using the profile_id but you can remove it

<?php
    session_start();
    if(!IsSet($_SESSION['user_id']) or $_SESSION['profile_id'] !=1)
    {
        header("location: http://www.yourdomain.com/login.php?message=Invalid user");
    }   
?>
Luca
  • 108
  • 1
  • 11
  • Thanks a lot for this - let me check. – TaneMahuta Jun 24 '15 at 16:24
  • Just to confirm, you want me to save the session variables as a separate file sessionCheck, then include this on the relevant pages before the header and put the session start... at the top of the header ? – TaneMahuta Jun 24 '15 at 16:29
  • Yes sessionCheck is the separate script you have to include at the top of the pages you want to protect. It is clear that you need to save the user profile details in the session variable after checking that the user exists in the database and that the login details are correct. – Luca Jun 24 '15 at 16:34
  • Thanks. I think these are two separate things on my page. In the header I am not checking any db for the user, I just want to check the session. Everything else is just done on the login page. – TaneMahuta Jun 24 '15 at 16:41
  • And this is correct, the user account should be checked at the beginning. The sequence is Login page which call a validation page where to check if the user exists and where to populate the session varialble that will be used later to protect the pages from not authenticated users – Luca Jun 25 '15 at 08:05
1

The following portion should go before include "system/config.php"; because it seems like this file is outputting and also the fact that the following code is not dependant on any other data.

session_start();
if(!(isset($_SESSION['login']) && $_SESSION['login'] != '')){
    header ("Location: login.php");
}

Second:

if(!(isset($_SESSION['login']) && $_SESSION['login'] != '')){

Should probably be: if(!isset($_SESSION['login']) && $_SESSION['login'] == ''){

meaning == '' and not != ''

A user not logged in will most likely (depending on your code) not have a value set so your code will check to see if it's not blank so only logged in users will get forwarded.

Hence:

<?php
define("someUnguessableValue", "anotherUnguessableValue");
session_start();
if(!isset($_SESSION['login']) && $_SESSION['login'] == ''){
    header("location:login.php");
}

include "system/config.php";
//.... the rest
?>
<!DOCTYPE html>
<html>
    <head>

If it's not forwarding, then $_SESSION['login'] is most likely set, you need to clear your cookies for that domain.

Onimusha
  • 3,348
  • 2
  • 26
  • 32