I'm using the MVC model (I think thats what its called) and I have separated my site into smaller pages and includes.... Is it safer/better or worse (with no benefit) to check the same conditional twice?
For example, I have an accounts page that looks something like this:
// Must be logged in
if(isset($_SESSION['userID'])){
include('edit_user.php');
}
and then in my edit_user.php page I have something like this:
// Must be logged in
if(isset($_SESSION['userID'])){
if(isset($_POST['editUser'])){
//Validate the form
}
?>
<form>
// Display the form
</form>
<?php
} // End main IF
So pretty much I'm checking if the user id is set twice... I'm pretty mush doing the same thing with all my pages (that require users be logged in). Is that really necessary? My initial thought was to prevent unregistered users from accessing the edit_user.php form directly and doing things (I was also thinking of just redirecting if users do access the page directly). What do you guys think/suggest?
Edit
I dont think I explained myself too clearly... That was just an example... Here's a better example to better get across the reasons for my question:
...Account page
if(isset$_SESSION['userID'])){
include('edit_user.php');// edit user form
include('change_password.php');// change password form
include('change_pic.php');// change photo form
}
and from within each of my includes, again I'm asking for a SESSION['userID']... So, what do you guys suggest now?
Well, it is redundant, which violates the "Don't Repeat Yourself" (DRY) principle of design. If your edit_user.php file is publicly accessible, then you definitely need checks in there, so you could probably remove the other checks, as long as you're sure of the functionality.
It's arguable that your code is clearer with the checks in place, however, in the long run redundancy like that will lead to more maintenance hassles.
You shouldn't need to have the multiple checks in there. If all requests go through the controller, then you should only need to add the check in the controller. That is the point of the controller, to direct the request. The view outputs data. The model interacts with the database (and enforces business logic).
In many cases redundancy is beneficial, but in your example it's unnecessary. It also goes against the principle of DRY (Don't Repeat Yourself). The more you repeat the same code, the more time you waste (you also face the possibility of adding errors to your code due to repetition). You should be fine with the check solely in edit_user.php.
Since you're using MVC, here's what I suggest: Define some authentication functions that are globally accessible. Then, in your controller's constructor methods, use them to see if the user should be granted access to that section. If they're not authorized you can redirect them to another page, or display an error message, for example. Of course you can use a finer-grained methodology and place the calls to your authentication functions in the beginning of certain controller methods.
You should always validate input that comes in from outside your control, so every php script that can be accessed by a user should check.
Even if you don't expect it, if a user can see a link in the url to a page that is 10 forms deep in your site then they can still jump directly to it.
Joomla uses a nice method, which is to put this right at the top of each PHP file:
defined('_JEXEC') or die('Restricted access');
_JEXEC is defined in the main entry point. You could do something like:
if ( isset($_SESSION['userID']) ) {
define('LOGGED_IN', 1);
include('edit_user.php');
}
With this in edit_user.php and other files:
defined('LOGGED_IN') or die('You must be logged in.');
Related
If I may ask, I would like to ask about "sessions", "controllers" and "session controllers".
So let's start at the beginning: I have heard of MVC and tried it in C# (VS), but while I could grasp the concept, I didn't understand implementation. It all seemed so strange. Now in PHP the concept became even more clear.
Now I would like to ask whether or not a "session controller" is like a controller for the session. It seems straight forward, in wording, but maybe I have it wrong. Although I would preferably not implement MVC in the current project I am working on, yet I would like to perform some sort of "controller" that manages groupings of session content.
Although I would like to ask if it is possible to have the following script in your application:
//path: c:/xampp/htdocs/starvationproject/root/index.php
<?php
include '../session/controller.php';
?>
<!DOCTYPE..........
//path: c:/xampp/htdocs/starvationproject/session/controller.php
//I have not coded this script yet, but it will perform tasks like
//setting the user, session variables etc.
<?php
session_start();
?>
// An important question here. If I include this file in the previous, can
// I safely say that the session has been started in index because of the
// include, or do you have to manually type out session_start();
// in each page?
Lastly, I would like to ask if this file structure is correct or not, or rather if it is standard or nor, or whatever:
Folder Structure
, where "multi" (as you can see) has a page named after each folder in "partial", where what I did is, based on the get request of the page in "multi", I included a partial, i.e:
if ($_GET['q'] == 'Add') {
include '../partial/stockAct/add.php';
}
else if ($_GET['q'] == 'Update') {
include '../partial/stockAct/update.php';
}
And then those "partial" files only held like a section with a form or something like that. As in the tv stays where it is, I'm just switching channels.
I'll do my best to help.
First let's talk about sessions. Sessions are used by the server to 'store' temporary information throughout a single browser session (this can be modified slightly but we won't go down that rabbit hole). In your specific situation, having a session Controller is unnecessary because the server handles all of the session logic. For example, on the login page, when the login form is pushed to a login script, you can simple add the user id to the session at that point and then no matter which page you move to, the user id will still remain in the session. The benefit is of course that you only need to set the session once and only access it when you require. This is where an MVC shines though as you can easily define a routing where all pages of a specific authentication type first go through to ensure the user is logged in/ has access to the page content.
For folder structure, I'd recommend some immediate changes. Firstly, I'm sure you are familiar with the talk of "public / public_html' folders? These folders are specifically name to represent the location where you put ALL of the files a front-end user would "see". This includes, front-end js files, css/ styles and in your case php PAGES. This folder SHOULD NOT however contain any back-end logic like database connections or verification scripts as this would give the front-end access to potentially sensitive information (ie. database login information which I am sure is found in your DB_Conn.php file).
To fix this I propose the following (assuming you would like to avoid the "MVC" structure).
ROOT
->Public //this is your WEB ROOT/ DOCUMENT ROOT folder
->Pages
->Style
->Scripts
->Assets
->Images
->etc.
->DB
->Connections
->db1_conn.php
->db2_conn.php
->Models
->User.php
->Posts.php
->Verification
->login.php
->etc
I'd like to finish with some advice as I used to build sites this way some time ago. MVCs take some time to learn, but their biggest advantage is the organization and flow of information. As a bonus, their process covers common issues like verification, security and data sanitization. Don't let them scare you, for the time it takes to learn then, they are well worth the capability you will gain from them.
I'd highly recommend Laravel. Version 5.5 just came out and oh boy is it a thing of beauty. Hope I could help at least a little!
This is probably a dumb question. I have a Web site that uses php and html with a bit of Javascript. I am trying to set it up so there are multiple landing pages. I think it would work if all the remaining .php files on the site were kept identical but there were separate index_a.php, index_b.php files, etc. The only problem is when the user clicks "Home" they of course get the root index.php. Is there a way to store the name (or some other indication) of what the user's landing page was for that session (using PHP session variables or I don't know what) and have the user directed to that page again when they click Home ?
Any help would be much appreciated (keeping in my mind I am a relative newby and any solution would need to be pretty simple and safe to load on a server). Any straightforward way way to do this ? It must be something that is fairly commonly required.
Short answer: yes
Smart answer: use a (mvc) framework of some kind which implements views and routes everything through a front controller.
Quick and dirty answer:
// anywhere
session_start();
$_SESSION['landing_page'] = 'landing-2.html';
// in your index.php
session_start();
include $_SESSION['landing_page'];
Note: if you use the code above, be sure the torn of the security gods will fall upon you.
In user-based websites, it is very common for websites to use a page like "logout.php", and I even use them myself on my own projects, but now I am wondering why. So my question is: Are there any specific advantages to using a dedicated file for logging out users? Would it not be more organized to just create a method within any appropriate class, such as:
Here is an example written in PHP (this is similar to what I have started to use):
public class Admin {
private function logout() {
$_SESSION[ADMIN_ACCESS_KEY] = null;
unset($_SESSION[ADMIN_ACCESS_KEY]);
return ($_SESSION[ADMIN_ACCESS_KEY]) ? false : true;
}
}
This function would then be triggered by some $_POST or $_GET variable, or any other way of doing it.
My only guess about why it is so popular (google, facebook, etc. do this last I checked) to use single dedicated file for the logout process it that you can simply direct the user to the page (logout.php) and they will be logged out no matter what, provided that the page loads and executes properly. Can you think of any good advantages for either method?
It's not necessarily its own file. In most cases the site is running an MVC where url parameters are parsed into class methods. So though you are visiting host.com/account/logout - you are just simply calling the logout() method in the account class (in its simplest form) in the easiest way possible from the browser.
You'd think this could be done with JavaScript by simply deleting the cookies on the client side, but best practice is to destroy the server stored session also, so it can't be recovered by anyone (like an attacker)
The biggest advantage i can think of is that it allows developers to keep logout type logout button, which are not dependent on jquery or any other client-side javascript to log you out. You just redirect/link them to another page, which takes care of removing their session data.
Its just a plain, and simple URL. Sometimes people even prefer typing it in the URL, i know i do!
The question is worded a bit strangely, but I couldn't figure out any other way. I'd like to know if there is a better model for doing this. Here's what I have now:
Say I'm editing a user on my application. I submit the form, and it POSTs to apply.php?ref=edituser. Then on apply.php, it has a large conditional to determine which settings are being submitted, based on the ref variable, at which point it runs that part of the script. If it succeeds or has an error, it uses header("Location: uedit.php") to return to the previous page, also setting $_SESSION['err'] with the error code. That page checks to see if the error code is set, and displays and unsets it if it is.
I feel like I might have too much in a single script. Any opinions on this?
Do multiple forms submit to it?
As a general rule a form doesn't submit to a model a form submits to a controller in the MVC structure. The controller then decides how it should handle everything. But if you comment everything well and don't think it is to much I wouldn't worry about it.
Depends on your style. Website I'm working on only uses 2 main php files. Only thing I would recommend is to make sure you comment well
The cons with this kind of system is like mentioned before, it can be hard to keep track of all code in a logic way.
An other con is that php is an interpreted language which means that the whole file need to be parsed on each run. That means that if you separate the code into different files instead of building a big one you will gain performance. But of course, if it is not to big it won't matter.
I'm currently writing a couple of MVC sites using Kohana as my framework. Each has a simple admin area where the admin can upload and edit content. I'm currently storing the admin's user model in a session and checking whether or not they're an administrator with the following method:
private function checkAdmin()
{
if (!isset($_SESSION['admin']) || $_SESSION['admin']->Level !== 'admin')
{
header('Location: /admin');
exit;
}
}
I call this method in all of the other Admin controller methods, like so:
public function writeReview()
{
$this->checkAdmin();
// rest of the method
}
I'm just wondering if there's anything I can do to improve this. It just seems like a single point of failure that's giving me a bad smell, so I'm a bit weary to move on before getting this nailed down.
If this is Kohana version 2.x, I would move the $this->checkAdmin(); into the constructor of your controller. If this is version 3.x, I would put it in the before() method. This will ensure that every route will be protected.
Your function appears to be redirecting to /admin only if the user is not an administrator. If that's the intended result, then fine.
-- Forget this, my mistake.
The checkAdmin() function, as it relies on a redirect, is only useful in situations where you want to redirect. If, for example, you are using this in the processing script (and you should be checking if it's an administrator in the processing script), you just want a return true or return false. I suggest that be the base function, and a redirect function call that, or alternative, accept and optional parameter to redirect.
If you want to let users share their logins fine, but otherwise generating a per session/login key and storing it in the DB will lock things down even further. This way, if someone logs in with your password, you'll get kicked out and instantly know that it's been compromised.
Other basic things to do - store dates of last login, IPs.. this kind of stuff. It's not just one single thing, but lots! :)