I have no idea if I worded that question correctly, but I worded it very carefully. So, basically here's the thing. I have two directories on my local machine.
/server/core/
and
/server/clients/
The "core" is what handles all of the data processing, this is done so that if I ever need to update my application then I will just have to update the "core" and all of the "clients" that include and call functions that are located in the "core" will be updated automatically. I believe the term for this is a "Dynamic website".
So, basically here's the thing.. I'm using very basic sessions for the time being just to start learning, but I will definately change things around once I'm at a more advanced level. Currently on my "core" i have the following code located in login.php
if(canLogin) {
if(!isset($_SESSION)){session_start();};
$_SESSION['email'] = $email;
header('Location: index.php');
}
Which will load the 'index.php' which is located on the "client" directory. Here's how I have this done.
The following code is located in /server/core/
function createIndex($SQLConnection, $SQLConfig, $PDOConnection) {
global $action;
global $days;
if(!isset($_SESSION)){session_start();}
if(empty($_SESSION['email']))
{
createLogin($PDOConnection, $SQLConfig);
}
}
The following code is located in /server/clients/
<?php
$Configuration = include_once 'inc/Configuration.php';
include_once 'inc/Connection.php';
include_once '/opt/lampp/htdocs/eDashboard2/core/index.php';
createIndex($NormalConnection, $Configuration, $PDOConnection);
?>
Which generates the Index.php file on the core and relays the website back using echos. Please ignore the multiple SQL Connections as it was for testing and will be removed.
So basically, what the problem is, is that the session isn't being saved, or... rather, if I had to guess the session is being stored on /server/core/ and not on /server/clients/
The end-result is that the user is always asked to log in, instead of being able to continue onto the website like they can in the "Client-Only" version of this. (( The client only version was just a static website like you would normally see, the dynamic approach is something I took upon myself to attempt to learn just for the experience ))
How can I make this so the session will be stored for the person logging in.
Use session_set_cookie_params to set the directory to the parent directory:
<?php
$params = session_get_cookie_params();
session_set_cookie_params($params['lifetime'], '/server');
If the sessions also have to exist between subdomains of your domain, you need an additional parameter:
session_set_cookie_params($params['lifetime'], '/server', '.website.com');
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.
I tried coding in the following way for one of the website over a localhost. say localhost/abc:
<?php
session_start();
$_SESSION['name']=$row['name']
?>
The output was good. but when the same code was used for another webpage over the same localhost say localhost/xyz. Then there was ambiguity between names. As if I need to distinguish between the sessions for xyz and abc.
So I tried this:
<?php
session_id(226);
session_name(veer);
session_start();
.
.
.//connection with database and all
.
$_SESSION['name']=$row['name'];
echo($_SESSION['name']);
?>
When another machine logged in over the same server then the session I created was accessible by that machine for same webpage.
Is there any solution. Or how to distinguish between two sessions.?
To put it in simple terms... you are accessing same memory area of server when you access two different sites on same web server using the same browser instance. Thus
http://localhost/xyz and http://localhost/abc are referring to the same site localhost and thus you will not start another session by session_start() but instead resume it. You can alternatively create virtual hosts as Jon said but for the sake of testing which I guess you are, just use different browsers.
Also, you cannot share session over different machines normally, so I think that's your logical mistake. Alternatively try
session_start();
echo (session_id());
on the top of the page and see if you are starting or resuming the same session which I think you are not. I think your page is storing same data in different sessions which you are mistaken as same session.
Use session_regenerate_id(); method in the second file(xyz).
this?
<?php
session_start();
if (!isset($_SESSION['xyz'])) { $_SESSION['xyz'] = array(); }
$_SESSION['xyz']['name'] = $row['name'];
?>
sometimes instead of doing the above i just prefix my session keys
example: $_SESSION['xyz_name'];
I did that after i realized that my CPanel has been used some sessions of its own
that caused a conflict to mine.
Requests from the same user agent to the same web server will share the same session, barring explicit configuration that depends on your exact server setup.
Normally this problem is avoided because the "other webpage" would actually be on another domain entirely, so the session cookie (and by extension the session data) would not be shared. This is also what you should do if you want to run separate applications independently on localhost: set up separate virtual hosts on separate internal domains.
You could also solve the problem purely in code by not using $_SESSION directly to store your data but a subkey based on some differentiating factor such as $_SESSION['SCRIPT_NAME']. A very simple example:
$sessionKey = "default";
if (strpos($_SESSION['SCRIPT_NAME'], "dir1/")) {
$sessionKey = "dir1";
}
else if (strpos($_SESSION['SCRIPT_NAME'], "dir2/")) {
$sessionKey = "dir2";
}
$_SESSION[$sessionKey]['mydata'] = 'foo';
However this last one is a really inelegant solution which I would not recommend.
I have a simple login page that checks credentials against database and then every page includes auth.php that verifies $_SESSION['logged'] is set and that session isn't expired.
Problem is that every page also includes another page tab.php (something like a menu), which I also need to restrict access to, but including auth.php inside tab.php makes the inclusion occur twice. If I don't include the auth.php in tab.php, though, anyone can access tab.php directly bypassing authentication check and possibly retrieve private information.
Any best practice to solve this situation?
EDIT:
And I forgot to ask, but what path you use to make it relative to site root? As both auth.php and tab.php are in folder and the index.php which includes tab.php is in root - the include function gives an error for either index.php or tab.php according to what path I use ('./includes/auth.php' OR './auth.php') - If you know what I mean. I tried '/includes/auth.php' but that doesn't work.
Use include_once instead of include in your files (or require_once and require). This will insure that your auth.php file will only be included once in the lifetime of the script.
include_once and require_once will definitely assure that you don't have the same file included more than once (at the same time make sure you're authenticated).
What I would do, however, is add your includes in a "include" folder and forbid access - to people who would type in the path manually - through an htaccess file. This way you could keep your includes in one place (whatever your header includes might look like) and keep your include files clean and still out of reach. If you were to do this you'd only have to do what Jan. mentioned in the answer above and check if your $_SESSION['logged'] is set (and whatever other checks you need)
Just check in tab.php if the session is initialized and $_SESSION['logged'] is true. This will work fine, if auth.php is loaded first.
What about using require_once("auth.php");? This makes sure, that auth.php is included (otherwise application will stop) but only includes the file once which seems to be your goal.
Try include_once(). See ( http://php.net/manual/en/function.include-once.php )
I have a form in a template which is posted to a PHP script. This script sets some variables in the $_SESSION array, then redirects back to the same page using the standard:
header("Location: index.php?page=enquiry-form");
The problem is that whenever the page loads after refirection, the session only contains the following three variables:
cmsuserkey
cms_admin_user_id
cms_admin_username
...all of mine have disappeared.
I'm calling session_start(); in my php script
I've set the config option: $config['use_smarty_php_tags'] = true;
The user doesn't need to be logged in to use the form (in fact the site doesn't use logins at all).
Can anyone suggest anything I'm not doing/doing wrong?
Thanks,
Rich
I had the same problem once and fixed it by addin exit() after the redirection to save the session:
header("Location: index.php?page=enquiry-form");
exit();
I've had a similar problem (though I wanted to use data from the CMS Made Simple session in another php-file). For me the cause was the following (as stated in my comment on the question):
CMS Made Simple (CMS from now on) does makes its own session name. This means that when you run session_start() in a separate php-file, it will not have the same session name. Therefore, the php-file won't be able to access CMS's session data, and CMS won't be able to access the php-file's session data.
The solution logically follows from the cause, you need them both to use the same session name.
CMS sets its session name in include.php which should be in the app's root folder.
$dirname = dirname(__FILE__);
...
$session_key = substr(md5($dirname), 0, 8);
#Setup session with different id and start it
#session_name('CMSSESSID' . $session_key);
So, in your php file you will need to do the following (before calling session_start();):
//Substitute the string $dirname for the result of __FILE__ in **include.php**!!!
$dirname = '/data/web/somefolder/someotherfolder/'
$session_key = substr(md5($dirname), 0, 8);
#session_name('CMSSESSID' . $session_key);
//Now you can call session_start();
Doing this lets your php-file access CMS's Session. If you use any plugins that put essential data in the session, you'll want to be careful not to erase any of that data.
NOTE: I use CMS version 1.8.2, this solution may not work if you use a different version.
The context:
I have a web application (e-commerce in few steps) written in php, I am writing a new version with CodeIgniter.
I have to include it within php pages generated by a CMS (sitezen).
/* generated html */
<?php include('my_app/index.php); ?>
/* generated html */
I cannot do anything about the CMS part, like working with an other one...
My problem:
With I cannot start the session before the header has been sent, I also get warnings when using the session but I can disable them.
My Workaround:
I didn't find any help relevant to my problem. The only workaround I could think of for the old php version is to send an ajax request to a php file starting the session.
This is working but there might be a better/cleaner solution, and I don't know how to do it with the CodeIgniter version.
I'd like to avoid using Iframes too!
If anyone knows a way to do it, or has any hint, it will be highly appreciated!
CodeIgniter is a good framework for doing everything in it (as most frameworks), but doesn't like being 'included' from outside.
Why do you need to include him into a different CMS? You may do the CMS in CodeIgniter (that's the base purporse of CodeIgniter), or the e-commerce in sitezen.
If it is because of the surrounding styles, the best it occurs to me is to have it coded also in CodeIgniter. That's not great because you have to mantain styles twice, but it is one of the cleanest ways of achieving what you want.
Warnings are there because of a reason: disabling them does not prevent the result from happening.
What happens to you is that you try to start a session that has already been started. In order to avoid that, you must give the second session a different name from the first. (In a call previous to session_start(), you'll want to call session_name().
Bad news are that once a session has been started, previous data from the session is no longer accesible, so if the CMS stores stuff in the session on __destruct(), the $_SESSION array where it stores the new data in will not be the same $_SESSION() used at the beginning of the CMS bootstrap.
And if you don't start a second session, you'll mix the CodeIgniter and sitezen variables inside the same array (beware of name collisions).
Code like this will NOT work (so, nesting sessions / restoring sessions is, as far as I know, not possible):
<?php
function show() {
echo "We are on [{$_SESSION['name']}] <br />\n";
}
session_name('SUPERSESSION'); session_start();
$_SESSION['name'] = "Super";
session_name('SESSION_ONE'); session_start();
$_SESSION['name'] = "ONE";
show(); # We are on [ONE]
session_destroy();
session_name('SESSION_TWO'); session_start();
$_SESSION['name'] = "TWO";
show(); # We are on [TWO]
session_destroy();
session_name('SESSION_ONE'); session_start();
show(); # We are on [empty] <- resume sessions does not work
session_destroy();
show(); # We are on [empty] <- nested sessions dont work
session_destroy();
To avoid headers already sent warning, start your code with ob_start() in your index.php, and ob_end_flush() at the end
Can't really be done without hacking the CMS considerably.
A CMS provides you with tools to do a specific job, so you are restricted to the CMS capabilities. Similiarly CI is a framework to help develop apps.
do you really have to include it within the CMS pages?
Why not create a link like:
site.com/my_store_app/codeigniter-stuff
then just link to it from within the CMS. You can reuse the existing template, so visually it will look like it's "within" the CMS, but you will be able to eliminate all these other problems.
You're essentially taking two completely different systems and attempting to stick them together.
I'm not sure if it would work for you but you could decide to include them trough curl. Another option is to include the pages directly. Do note that I'm not sure if this would work but if it does you won't be able to send PHP variables to it except trough the link.
include('http://www.example.com/codeigniter/controller/method/id');
Try this. If it works you can do something like this to control it:
include('http://www.example.com/codeigniter/'. $controller .'/'. $method .'/'. $id);
Note: sessions won't work on this method. If you really want sessions to work your best bet would be to separate the applications.
www.example.com <-- your cms
www.example.com/store <-- your webstore in CI