I'm designing a website (as an absolute beginner) and I've encountered an issue. You can easily log in with this script:
http://pastebin.com/0HZkQxXg
That script works fine, however, you can just as easily type in "addressofserver:homepage.html". How do I authorise the log in? Do I need to put a script on my index files to kick people off unless they've logged in first?
How would you do this?
Thank-you.
You need to actually be running the pages as .php not .html as you stated in your question.
You'll also needed to check if the user can/is allowed to access the said page. That means you check the session that you just set:
<?php
session_start();
if(!isset($_SESSION['loggedIn']) || !$_SESSION['loggedIn']) {
die(header("Location: /loginpage.php"));
}
?>
Also, on every page that you need to access any session variables, you will need to start the session with:
session_start();
That means on your login processing script as well (the one you posted).
Related
The context:
I'm building a PHP 7 web application, it uses a PHP session to login and check to see if the user is logged in on each page. Here is the basic makeup of most pages:
<?php session_start(); ?>
<?php include 'the_header_and_menu.php'; ?>
<p>Page content</p>
<?php include 'the_footer.php'; ?>
At the top of the_header_and_menu.php file is an include to session_check.php which is located outside the site's directory. This PHP process does five checks, the most basic one included below.
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] == 'false') { // If loggedin is not set, or is false, then run this block.
header('Location: http://example.com/index?eject=noLogin'); // Send the user to the eject page.
die(); // Exit the process.
}
Process summary: User logs in, which creates a session and its variables. When the user loads a page, a session check is performed to make sure that the user's account is valid and authorised. If the account or session is no longer valid/authorised, then the user is redirected to the login page (index).
The issue: When someone who's not logged in enters http://example.com/dashboard, they are ejected using the first check (featured above). However, if they enter http://example.com/process/, the checks seem to count for nothing and the user is shown the page. This page does not just include a directory listing, but calls the http://example.com/process/index.php file to represent it instead.
The question: How can I apply the same logic that protects individual pages like dashboard.php, to the case of protecting directory indexes?
Own answer:
The issue here was one which was simple, but overlooked.
At the top of the_header_and_menu.php file is an include to session_check.php which is located outside the site's directory.
Within the header and menu file was the session check include. However, because the session check was located outside the main directory (like much of the back-end), I had referenced to it through a relative path, similar to the one below.
include_once '../mainfolder/php/subfolder/sessioncheck.php';
However, because the file was being included to a subdirectory, it should've included a further ../ operator.
include_once '../../safe/php/users/sessioncheck.php';
The solution: Instead of performing a session check through the header and menu, I am now including it on every page I want to protect. This is by no means a perfect solution and simply acts to get things working again.
Thank you to Daniel Schmidt, who got me looking in the right direction!
Directory indexes don't usually come from PHP - they are served by your webserver (nginx, apache, ..). Today, there is obviously no need to have that indexes enabled.
It looks like you're not sending each request to you're PHP process(es). I tend to suggest checking your webserver configuration.
The issue here was one which was simple, but overlooked.
At the top of the_header_and_menu.php file is an include to session_check.php which is located outside the site's directory.
Within the header and menu file was the session check include. However, because the session check was located outside the main directory (like much of the back-end), I had referenced to it through a relative path, similar to the one below.
include_once '../mainfolder/php/subfolder/sessioncheck.php';
However, because the file was being included to a subdirectory, it should've included a further ../ operator.
include_once '../../safe/php/users/sessioncheck.php';
The solution: Instead of performing a session check through the header and menu, I am now including it on every page I want to protect. This is by no means a perfect solution and simply acts to get things working again.
Just a newbie here so please pardon my mistakes.
I'm working on a website using .shtml pages (SSI).
I'm trying to include a PHP script into my .shtml page.
Up to this point everything is working fine:
PHP script gets included and it does what it was intended for.
Here is the actual example.
There is the home page (index.shtml) including a script called security_check.php with this directive:
<!--#include virtual="includes/security_check.php?idOp=000&idPage=0000" -->
This is the PHP code for security_check.php:
<?php
session_start();
include('config.php');
include('myfunctions.php');
include('security_functions.php');
$idOp = $_GET['idOp'];
$idPage = $_GET['idPage'];
$allowedReferer = array();
// Connection to the database (defined in myfunctions.php)
$link = DB_Connect($DBhost, $DBuser, $DBpass, 1, $DBname);
// Check if the PHP session already exists. If not, create one
// (that is insert a record in the DB and returns the id, which
// will be stored in the PHP session variable).
// user ID is 0 because not logged yet
if (!isset($_SESSION['idSess'])) {
$_SESSION['idUser'] = 0;
$_SESSION['idSess'] = create_session(); // security_functions.php
}
// Please note that create_session() correctly use $_SESSION['idUser']
// in order to do its work, even if it's not passed as a parameter
// (as it should be: $_SESSION is a superglobal!) and the same goes
// for activity_supervisor().
// Defined in security_functions.php:
// it uses both $_SESSION['idUser'] and $_SESSION['idSess']
activity_supervisor($idPage,$allowedReferer,2,$link);
mysql_close($link);
?>
At this point,
home page is correctly displayed and there is a 'Sign up' button
in it, calling sign.shtml.
This sign.shtml page include the very same security_check.php script
with the exact same include directive already seen above except for the value of idPage parameter which in this case is 0001.
I would expect the script to recognize the PHP session and therefore
not creating a new session, but indeed a new session gets created every time.
I already read every other post related to PHP sessions not working and I even tried the solutions proposed there.
- session_start() is written on top of every script because there is just one script
- session.save_path equals to /var/lib/php/session and is writeable by the web server
- I already tried to set session.gc_probability = 0 and restarting the web server (to no avail, so I got back to session.gc_probability = 1)
- I tried with different browsers (namely, Firefox and Chrome) with the same results
So I tried the following test (note those two empty lines BEFORE session_start(): I always space instructions this way to improve readability)
creating a simple test.php script
<?php
session_start();
if (!isset($_SESSION['foo'])) {
$_SESSION['foo'] = 1;
echo ('Value is '.$_SESSION['foo'].'<br/>');
echo ('Refresh');
}
else {
$_SESSION['foo']++;
echo ('Value is '.$_SESSION['foo'].'<br/>');
echo ('Refresh');
}
?>
Well, believe it or not, every time I hit 'Refresh', the value
is incremented, so PHP recognize the session (the test.php script is inside the same domain as the index.shtml and sign.shtml pages).
I even tried to make the PHP script to show a link to a .html file (not .shtml) which then show a link to test.php. It works correctly!
It really seems that the session is not correctly set only when the PHP script is included into the .shtml page, even if I don't see any reason for that. Maybe you know why and, above all, how to circumvent this boring behaviour? Is it a feature? Does it depend on a parameter setting in php.ini?
Final tips:
OS: CentOS 6.3 with 2.6.32-279.el6.x86_64 kernel
Server version: Apache/2.2.15 (Unix)
PHP 5.3.3
Server is mine so I can configure everything, if needed.
Thanks in advance and forgive me for the long post: I tried to make it
clear that PHP sessions do work perfectly in every other situation I know of.
I don't think this will work because the SSI will execute the PHP script, and then send out its output to the web server. You would need some way of rewriting URLs so that they do not rely on cookies, since cookies get "eaten" before the server gets to send them to the browser.
Try using
ini_set("session.use_cookies",0);
ini_set("session.use_trans_sid",1);
and then you'll need to send the SID in the outgoing URLs (and on POST pages, too). See this answer for example.
Specifically, you need to redirect the user not to sign.shtml but to something like
$sidkey = session_name();
$sidval = session_id();
print "sign up: here";
and include this in the SSI output.
UPDATE: the root of the problem is that the SSI cannot create a session (cannot send anything but plain HTML. Sessions that use cookies rely on headers, not HTML only). But if you create the session with a PHP script launched outside SSI, that is able to set a cookie, from that point onwards all PHP scripts (whether SSI or not) are able to read the cookie and therefore will be able to access and modify the session (which is a file/memory/Redis/other on the server identified by the session cookie's value).
You can check whether a cookie is set in SSI, and if it not, you can redirect to a pure PHP page that sets the session cookie and sends back to the original shtml using a HTTP Redirect.
I have been working on a website and had the following code...
<html>
<?php
session_start();
//if not logged redirect
if(!$_SESSION['logged']){
header("location:restricted.php");
}
else
//else continue and display the rest of the page
{
//html page content here
?>
...obviously what this does is check if session variable 'logged' is set and if not the user will be redirected to restricted.php, otherwise the rest of the code (this page)will be diaplayed.
This was on a server working fine, but I have just gone with an alternative host (and obviously server) and if the session is not set, the user simply has a blank white page (which is titled with this page, not restricted.php).
Does anybody have any idea why this is happening?
Thanks very, very much in advance...
You cannot output anything to browser before calling session_start() - it must come before all output, otherwise an error will be throw - Headers already sent
Correct way:
<?php
session_start();
//if not logged redirect
if(!$_SESSION['logged']){
header("location:restricted.php");
}
else
//else continue and display the rest of the page
{
//html page content here
?>
<html>
It could not have worked in the first place, though!
The problem is, that you send output before you start the session, by having the "" output before starting the session.
You should set the php-block in front of everything (which also makes the else-branch obsolete, because you get redirected before content is displayed.
So the code is then:
<?php
session_start();
if(!$_SESSION['logged']){
header("location:restricted.php");
}
?>
<html>
<!-- This is only visible if you're logged in! -->
Maybe you can compare the Session variable with NULL may be it will be more clear.
And don't forget to put your session_start(); before anything else on your page.
Thanks every1 it worked...i know it sounds a bit wierd, but on the old server it did actually work with the HTML before the session_start(). I did it on dreamweaver and it had all the usual rubbish dreamweaver puts in:
...and if a moved this BELOW the session start it was a blank page, now its the other way round, it does let me put it below and works fine...wierd i know.
Thanks again for all the replies :)
Since your site is not configured to display error messages in the browser itself, you need to check PHP's error_log to learn exactly what the error is.
Many shared hosts provide a method for viewing error logs, or at least showing you where they're located from with your hosting account panel. If you have ssh access you can find the path to this file with:
$ php -i | grep error_log
Alternatively you can create a PHP file on your server with the following:
<?php
phpinfo();
and then load that file in your browser and look for the error_log configuration setting.
With the path to your error_log, if you have ssh access to your account you can enter
tail -f /path/to/your/error_log
While the above command is running, load the webpage showing the blank page. Your terminal will dump the contents of the error_log as it's updated. If you don't have ssh access, it's possible your host provides a method for viewing errors generated by PHP for your site.
Only then will you have the information you need to fix whatever is causing the blank page.
What is the best way to "NOT" display a page directly in php?
Edit
There is a page = register.php
a user cant open register.php directly. Only can access from index.php > Register.php
Thanks
Any PHP files containing sensitive data, such as database password, should be stored outside of the document root and included where needed. That way, if an admin makes a serious mistake and the web server starts sending PHP unparsed, that data will be inaccessible.
Edit
You edited your question and it now seems you wish to prevent access to page without them coming from a particular page. You should be able to get some ideas from these questions:
deny direct access to a php file by typing the link in the url
preventing direct access to a php page, only access if redirected
I think you want something like this:
if ( $_SERVER['HTTP_REFERER'] != 'http://YOUR_SITE/index.php' ) {
echo "Can't access this page from this referer";
die();
}
// go on with your register.php code
You can put
die();
or
exit();
At the top of your PHP document. However, your question is unclear as to what you wish to accomplish.
You can start a session in index.php and check for a certain variable from that session in the other pages.
make a file index.php
in it put
<?php
include 'register235235235235.php';
?>
make a file register235235235235.php
put whatever you want in there
As far as securing php includes, I only secure my database.php files which contain usernames and passwords.
I am making a simple Dynamic Website using PHP, where i allow the user to login and then access specific pages. So here's what i have done so far.
The logged in values are taken though $_POST variables in a php script where it fetches values from database for registered users. If the user is found i do the following:
session_register('userid');
$_SESSION['userid'] = $username;//this is taken from $_POST
$_SESSION['accesslevel'] = $access;
at the beginning of the php script i have put session_start();
Now here comes my problem.
At every page now i have to check if the user is allowed to view that page or not, if he ain't then he must be redirected to login.php, if he is then the page load must continue.
Now so far what i have learnt is that only way to maintain values across php pages is to use $_SESSION variables, and which ever page i am using Session Variables i must write session_start() on each page as the first line, else i will be getting Headers Already Sent error..
Strangely i exactly have done that but still get erros with the "headers already sent".
SO i want to what is the best way to design a website, where i have to use Session variables across most of the pages, and keep these common checks at a common place..
Can i use include() feature some how?
Are sessions only way to communicate data across php pages.
What is a better way?
I have the following code :
<?php
session_start();
if(!isset($_SESSION['user']))
{
$_SESSION['loc'] = "adminhome.php";
header("location:ettschoollogin.php");
exit();
}
?>
Which resides on top of every page which wants to check if the user has logged in.
And this is teh script to check for login
<?php
session_start();
include("connection.php");
$userid =$_POST['userid'];
$userpwd =$_POST['userpwd'];
$query="Select UNAME,UPASSWORD,SCHOOL,uaccess from schooluser where uname = '$userid'";
$result=mysql_query($query) or die("couldn't execute the query");
$row=mysql_fetch_array($result);
$useraccess = $row["uaccess"];
$school =$row[2];
if(($row[0]==$userid)&&($row[1]==$userpwd))
{
session_register('userid');
$_SESSION['userid']=$userid;
$_SESSION['school']=$school;
if($useraccess =="admin")
{
header("Location:adminhome.php");
}
if($useraccess !="admin")
{
header("Location:school_main.php");
}
}
else
{
header("Location:ettschoollogin.php?err=1");
}
?>
i was aware of the common error of having extra spaces after "?>", BUT I STILL GET IT.
Thanks guys, i missed out and the "connection.php" file actually had extra spaces after "?>" i had removed it before, but some how the file got rewritten again.Thanks a lot.
Yes, you can use include. Put all your common functions in a separate php file and "include" it at the top of each file.
You can use cookies to store information (typically just an id that you use to look up additional information in the PHP page). Normally, PHP sessions are handled using cookies though. See setcookie in the docs.
You are probably getting the error messages due to stray characters outside of a <?php ?> block. A common error is to have an extra blank line at the end of an include file, after the ?>. That blank line will be output and your headers will have been sent. If that isn't the problem, you will just need to make sure you move the session related code above any code that might generate some output (eg by using print or echo).
•Can i use include() feature some how?
Yes. You can do whatever you want before your session_start() call, only, you must not have outputted anything, not even a single space or character. Probably you have already outputted something, maybe on an automatic inclusion or apache prepend.
•Are sessions only way to communicate data across php pages.
•What is a better way?
Other ways are cookies, post and get parameters. But sessions are the only way to securely pass data among pages without sending them to the client and back (which may pose security risks)
Write ob_start(); at the top of your code and then you dont get the error of "headers already send"