Authentication using $_SERVER['SCRIPT_NAME'] - php

The users when they sign up are given a default 'member_type' as "User". I'm trying to restrict access to certain pages from "Users" and unauthenticated visitors using $_SERVER['SCRIPT_NAME'] using a function stored in the header.php.
The concept is sound (I believe) but I really need some fresh eyes to help me solve the logic.
Here is the function in the header:
$basicAuth = array("member.php", "order.php", "logout.php");
$adminonly = array("admin.php", "v_feedback.php", "user.php", "v_content.php", "product.php");
restrictAccess($basicAuth, $adminonly);
And here is the function in its entirety:
function restrictAccess($basicAuth, $adminonly){
$error = "You do not have the authentication privileges to access this area, go home.";
if (isset($_SESSION['type'])){
$auth = "Basic";
if($_SESSION['type']=="Admin"){
$auth = "Admin";
}
} else {
$auth = "None";
}
//For testing purposes
echo $auth;
if ($auth == "None"){
if(($_SERVER['SCRIPT_NAME']==$basicAuth)||($_SERVER['SCRIPT_NAME']==$adminonly)){
echo $error;
exit();
}
}elseif($auth =="Basic"){
if(($_SERVER['SCRIPT_NAME'])==$adminonly){
echo $error;
exit();
}
}
}
I have a feeling that it something to do with the logic behind the way I've structured it which is to fault.
Thank you.

if($_SERVER['SCRIPT_NAME']==$basicAuth) is completely wrong.
You can not compare array and a string.
if(array_search($_SERVER['SCRIPT_NAME'],$basicAuth) !== FALSE) would serve, but You better use keys instead of values, and then if(array_key_exists($_SERVER['SCRIPT_NAME'],$basicAuth)).
And, by the way, isn't it simplier to include "basicAuthNeeded.php" into some scripts and "adminAuthNeeded.php" into other instead of Your method?
Or else use more complex but more flexible method (define some roles, define resources and use some checkPermissions($role, $resource))?

Related

How to validate authentication header in multiple functions in PHP

I'm trying to use JWT to create a authentication system using AngularJs and PHP. I understood the concept of JWT, I can modify the headers and send my access token, etc... My doubt is on the logic to elaborate this since I have a lot of different functions.
For example, I have a file called client.php where I have client related functions, such as getClient, updateClient, insertClient, etc.. The same applies for other files, product.php, category.php, filter.php and so on.
So, how am i supposed to do this token validation before actually running any of these functions?
I tought of creating a common function and use it inside each function, for example:
function.php
function checkToken($token) {
$serverToken = //getting server token;
if($token !== $serverToken) {
return false;
}
}
client.php
require_once 'function.php';
$tokenError = array('status' => 'Unauthorized');
function insertClient() {
global $tokenError;
$accessToken = $_SERVER['HTTP_TOKEN'];
if(!checkToken($accessToken)) {
return $tokenError;
} else {
//Proceed with the function
}
}
function getClient() {
//Repeat samething as insertClient
//...
}
But it doesn't feel like the proper way to do this. So, is there a better, or a correct way, to do headers validation/authorization on each http request the user make?

PHP Login system hard coded username and password

I had to do a basic login system to protect a page, and I have no access to database so i store the username and password hard coded in php page.
My question is, can this login system hold againts an attack? I need it to hold about 1 month.
Any sugestions to improve will be helpefull.
The code is not in laravel, even if it might look like.
The username and password, will be changed to something stronger of course.
Thank you in advance.
<?php
class UserController {
private $username;
private $password;
private $isLoggedIn = false;
// Credentials
public function credentials() {
$credentials = array(
array(
"username" => "telekom",
"password" => "1234"
),
array(
"username" => "telekom2",
"password" => "1234"
)
);
return $credentials;
}
// Basic login
public function login() {
foreach ($this->credentials() as $credential) {
if ($this->username == $credential['username'] && $this->password == $credential['password']) {
Session::put('username', $this->username);
Session::put('password', $this->password);
$this->isLoggedIn = true;
}
}
}
// Get login status
public function isLoggedIn() {
return $this->isLoggedIn;
}
// Logout
public function logout() {
// Delete all sessions
Session::all();
redirect('/telekom/');
}
// Telekom
public function telekom() {
$form = new Form();
if (Input::get('logout') == 1) {
$this->logout();
}
// Post Data from login form
if (Input::has('username') || Input::has('password')) {
if (!$form->isCsrfValid()) {
$form->errors['CSRF'] = "CSRF Token";
} // CSRF protection is on, comment to disable
if (empty($form->errors)) {
$this->username = Input::get('username');
$this->password = Input::get('password');
// Check Login
$this->login();
if (!$this->isLoggedIn()) {
Session::put('login', 'Username and password do not match.');
} else {
redirect('/telekom/');
}
} else {
Session::put('login', '<p class="color-dark-red"><strong>Errors:</strong></p>
<p>' . $form->displayErrors($form->errors) . '</p>');
}
// Check if session has username and password
} elseif (Session::has('username') && Session::has('password')) {
$this->username = Session::get('username', false);
$this->password = Session::get('password', false);
// Check Login
$this->login();
}
}
}// EOF Class User
// Outside class
$user = new UserController();
// Outside class
if (!$user->isLoggedIn()) {
// display login form
} else {
// display protected content
}
?>
My comments are getting lengthy, so I'll just move them here. I would not recommend you put the username and password in the same file. If PHP ever fails to process the page, it will be dumped as plain text to the user. Even for database connections (where the un/pwd almost have to be stored plain text), most people don't put the information in the same file.
You have a couple options:
Make a separate PHP file that sets your UN/PWD variables, put it somewhere that isn't accessible from outside your server, and include it in index.php. In this case, I wouldn't include the file until right when you're going to compare the variables and let the local scope dump it as soon as possible.
Since this is such basic authentication, you could use Apache's built in password authentication module.
in my opinion, this solution is safe enough when you don't plan to use it forever.
What would I check is setting of your web server - some text editors makes backup copies of edited files, like index.php~, index.php.bkp or so. Make sure whether your web server do not serve those files, if any.
The problem with temporary solutions is that they've never temporary.
Never hard code passwords. Some of the reasons are:
It is harder to keep source code secret than it is a key.
Any vulnerabilities in your site that allow reading of source code may reveal the password.
Passwords from development will end up in production.
It is impossible to change passwords without redeploying.

Where in my MVC PHP app do I put this build function?

I'm trying to convert my PHP app into more of an MVC app. I don't have much experience with MVC and I don't fully understand some of/all of the concepts or how to do it with PHP, so I need some help understanding where a particular function goes.
This function returns some HTML depending on if the user is logged in.
public function buildLoggedInMessage() {
if ($this->User->isLoggedIn()) {
return ' You are logged in as <strong>'.$this->User->getUsername().'</strong> (logout)';
} else {
return ' Login';
}
}
My initial thought was to place this function in my "controller" because it asks the User model if they are logged in (which checks the database record), however it "builds" some HTML, so maybe it should be in the view. Should I move it?
I will eventually move the HTML from the function into a template, so ignore the inline HTML.
Would the function be more suitable in the view if it was like this:
public function buildLoggedInMessage() {
if ($this->Controller->isLoggedIn()) {
return ' You are logged in as <strong>'.$this->User->getUsername().'</strong> (logout)';
} else {
return ' Login';
}
}
and the controller asks the model if the user is logged in?
Thanks.
I think view should not contain any business logic. Views should focus on presenting stuff, so your second solution is bad practice.
More than that, since views focus on the presentation and models handle most of the business logic, controllers should do only the necessary things to link views and models, which means fetch data from model and just insert the data into the view.
so this line of code make no sense because it means you implement business logic in controller:
$this->Controller->isLoggedIn()
Now let's see your first solution.
public function buildLoggedInMessage() {
if ($this->User->isLoggedIn()) {
return ' You are logged in as <strong>'.$this->User->getUsername().'</strong> (logout)';
} else {
return ' Login';
}
}
This function 'return' htmls rather than 'echo' htmls. So who is calling this function? and who will 'echo' the string from this function? I would say this is not a complete controller.
In modern web MVC, there's always some kind of 'router' handle the http requests and execute some instructions related to that. Since you wanna implement MVC pattern, you need to implement that 'router' first.
For example, you can create a 'Member' class which has a 'check' method to achieve the functionality you want.
class Member{
public function check() {
if ($this->User->isLoggedIn()) {
echo ' You are logged in as <strong>'.$this->User->getUsername().'</strong> (logout)';
} else {
echo ' Login';
}
}
}
And you need to implement the router class to handle http requests like 'http://myweb.com/member/check'.
The router code would be something like this:
$url_segments = explode('/', $_SERVER['REQUEST_URI']);
if (count($url_segments) == 4){
$controller_name = $url_segments[2];
$method_name = $url_segments[3];
}
else if (count($url_segments) == 3){
$controller_name = $url_segments[2];
$method_name = $this->default_method;
}
else if (count($url_segments) == 2){
$controller_name = $this->default_controller;
$method_name = $this->default_method;
}
$this->current_controller = $controller_name;
$this->current_method = $method_name;
require BASEPATH . '/controller/' . $controller_name . '.php';
$class_name = ucfirst($controller_name);
$controller = new $class_name($method_name);
call_user_func( array( $controller, $method_name ) );
Create a MVC framework is not an easy work.
I create a simple MVC framework for educational purpose.
https://github.com/howtomakeaturn/PigFramework
Check the index.php file, and you will know what I mean router and controller.
I don't think that the point of MVC is to put HTML in a controller, if I were you I'd send some data back and make an if else statement in my view based on the send data. To make good use of an MVC you first need to understand what it is or does, so I'd recommend searching for a tutorial.
put this function in the controller from where you are calling a login function after if a user authenticated then it will set the session or flash data i.e $this->session->set_flashdata('success', 'you are loged in as $username');
else
redirect('login');

apply and call a session in different controllers

I am using zend framework. I have built a simple login screen. when the user logs in, I want to set a session and then in the init function of the member area controller its meant to check for the session and grant access, else, redirect to login screen.
I have set my login controller like so, this check the username and password and sets the session:
if (isset($_POST['loginSubmit']) && $form->isValid($_POST)){
$inputtedUsername = $_POST['username'];
$inputtedPassword = $_POST['password'];
if ($inputtedUsername == $username && $inputtedPassword == $password) {
$loggedIn = new Zend_Session_Namespace('loggedIn');
$loggedIn->success;
$this->_forward('index', 'home');
} else {
echo 'invalid';
}
}
I have a home controller, which only logged in users should be able to see, so in the innit function I have:
$loggedIn = new Zend_Session_Namespace('loggedIn');
if (isset($loggedIn->success)) {
echo 'success';
}else{
$url = $this->view->url(array(
'controller' => 'index',
'action' => 'index'));
header('Location:' . $url);
}
}
when i log in, using the correct credentials, it redirects me to login screen as stated in the else function.
what am i doing wrong?
First your use of Zend_Session_Namespace is incomplete (you never assigned a value to the namespace):
$loggedIn = new Zend_Session_Namespace('loggedIn');//here you created a namespace
$loggedIn->success;//here you created a key in that namespace with no value
The way your code seems to be structured any value assigned to $loggedIn->success would return true, so maybe try :
$loggedIn = new Zend_Session_Namespace('loggedIn');//here you created a namespace
$loggedIn->success = true;
While this might fix your current issue, I want to suggest you take a look at two Zend components that can really help with authentication and authorization.
The first is Zend_Auth, a component that deals with application authentication and will also help handle user session persistence. Rob Allen has a tutorial to help get you started.
The second is Zend_Acl, The Access Control List component, deals with authorization, who has access to what. A place to start with Zend_Acl

How to replace "Login" button with user name in CodeIgniter

I'm trying to create a universal header for a website built on CodeIgniter, and I'm having trouble figuring out the code that will switch the 'Login' link for the user's name (with a link to the profile page) after the user logs in.
In the controller functions, I've tried the following code:
if(!$this->session->userdata($userSessionVar))
{
$data['header_output'] = "<li><a href='" . base_url() . "index.php/main/login'>Login</a></li>";
} else
{
$data['header_output'] = $this->session->data('userFirstName');
}
(I realize this is incomplete, based on my designs, but it's just to test.) $userSessionVar holds the value "logged in" once logged in. Probably not the best way to do that. And that doesn't seem to work (and I pass the $data to the view). I've also tried making a custom function:
function check_login()
{
$CI =& get_instance();
$userSessionVar = 'logged_in';
if( ! $CI->session->userdata($userSessionVar))
{
return false;
} return true;
}
And then use the true/false return to structure the $header_output variable. None of these seem to work. I'm new to CodeIgniter and have some intermediate level of PHP/HTML/CSS, etc. I'm sure I'm missing something obvious and would appreciate any help, as well as a heads-up on how to avoid including the code in every controller function.
The variable $userSessionVar is only available within the function check_login(), so when you try to use it outside of the function, it will be blank (and therefore useless).
I recommend that you simply use $this->session->userdata('logged_in') and $CI->session->userdata('logged_in') rather than using the variable $userSessionVar to store what appears to be a constant value.
Also, you have an error in your code. You need to replace $this->session->data('userFirstName') with $this->session->userdata('userFirstName')
Here's how I typically deal with user data. First, add auth.php to the models folder:
<?php
class Auth extends Model {
private $user_data = false;
function Auth() {
parent::Model();
if ($this->input->post('action') == 'login') $this->login();
else if ($auth_id = $this->session->userdata('auth_id')) {
$user = // load user data from the database into the variable $user
if ($user) {
$this->user_data = $user;
} else $this->session->unset_userdata('auth_id');
}
}
function login() {
// process POST, check with database, and then store user_id using
// $this->session->set_userdata('auth_id', $user_id_here)
}
function me() {
return $this->user_data? (object)$this->user_data : false;
}
}
?>
Then, auto-load the model. To do this, edit config/autoload.php like so:
$autoload['model'] = array('auth');
Now your IF statement could look like this:
if ($me = $this->me()) $data['header_output'] = $me->userFirstName;
else $data['header_output'] = '<li>Login</li>';
in your model auth.php you've got the statements
class Auth extends Model
and
parent::Model();
With CodeIgniter, should these not be "CI_Model"...?

Categories