Prevent duplicate code with checking sessions - php

I have three session levels:
session->is_logged_external
session->is_logged_admin
session->is_logged_staff
I have a small function bellow (checkLogin) that I call to display a message if they do not have the session needed to accesses the page.
As you can see I have commented out code at a attempt to create a function that checks if the session is in one of these categories if so let them see page if not display message.
public function checkLogin()
{
$logged_admin = $this->session->is_logged_admin;
//$logged_external = $this->session->is_logged_external;
//$logged_staff = $this->session->is_logged_staff;
if(!isset($logged_admin) || $logged_admin != TRUE) {
echo 'Im sorry, you do not have administrator pillages';
echo anchor('main/index', 'Return home');
die();
}
//else if(!isset($logged_external) || $logged_external != TRUE) {
//echo 'Im sorry, you do not have external pillages';
//echo anchor('main/index', 'Return home');
//}
//else if(!isset($logged_staff) || $logged_staff != TRUE) {
//echo 'Im sorry, you do not have staff pillages';
//echo anchor('main/index', 'Return home');
//}
}
This did not work so I commented the code out. My next idea was to create three functions one for each of the sessions and call what functions I need for each page within the controller however, this is basically the same code repeated 3 times but with different session names, Is this the right way of doing this ?
Thanks guys.
example of idea two
First Admin session function
public function checkLoginAdmin()
{
$logged_admin = $this->session->is_logged_admin;
if(!isset($logged_admin) || $logged_admin != TRUE) {
echo 'Im sorry, you do not have administrator pillages';
echo anchor('main/index', 'Return home');
die();
}
}
Second Staff session function
public function checkLoginStaff()
{
$logged_admin = $this->session->is_logged_staff;
if(!isset($logged_staff) || $logged_staff != TRUE) {
echo 'Im sorry, you do not have staff pillages';
echo anchor('main/index', 'Return home');
die();
}
}
and a third that would be external, then I could call each one when I need them, right?

Related

Session loses variable stored after parent.location.reload() called in PHP

Below is the main code that goes to the session and constructor after it stores data in the session.
if(!$result->uid) {
$this->member_model->scripts("Wrong ID or PWD.");
} else {
$userdata['uid'] = $result->uid;
$this->session->set_userdata($userdata);
//header('location: /adminBase.php');
echo "<script>";
echo "parent.location.reload();";
echo "</script>";
exit();
}
On the login part, it stores UID through $this->session->set_userdata($userdata);,
Here is the part where it stores
public function set_userdata($data, $value = NULL)
{
if (is_array($data))
{
foreach ($data as $key => &$value)
{
$_SESSION[$key] = $value;
}
return;
}
$_SESSION[$data] = $value;
}
but when it goes to the constructor through
echo "<script>";
echo "parent.location.reload();";
echo "</script>";
it removes previous session that keeps UID.
if ($class instanceof SessionHandlerInterface)
{
if (is_php('5.4'))
{
session_set_save_handler($class, TRUE);
}
else
{
session_set_save_handler(
array($class, 'open'),
array($class, 'close'),
array($class, 'read'),
array($class, 'write'),
array($class, 'destroy'),
array($class, 'gc')
);
register_shutdown_function('session_write_close');
}
}
else
{
log_message('error', "Session: Driver '".$this->_driver."' doesn't implement SessionHandlerInterface. Aborting.");
return;
}
// Sanitize the cookie, because apparently PHP doesn't do that for userspace handlers
if (isset($_COOKIE[$this->_config['cookie_name']])
&& (
! is_string($_COOKIE[$this->_config['cookie_name']])
OR ! preg_match('/^[0-9a-f]{40}$/', $_COOKIE[$this->_config['cookie_name']])
)
)
{
unset($_COOKIE[$this->_config['cookie_name']]);
}
session_start();
// Is session ID auto-regeneration configured? (ignoring ajax requests)
if ((empty($_SERVER['HTTP_X_REQUESTED_WITH']) OR strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest')
&& ($regenerate_time = config_item('sess_time_to_update')) > 0
)
{
if ( ! isset($_SESSION['__ci_last_regenerate']))
{
$_SESSION['__ci_last_regenerate'] = time();
}
elseif ($_SESSION['__ci_last_regenerate'] < (time() - $regenerate_time))
{
$this->sess_regenerate((bool) config_item('sess_regenerate_destroy'));
}
}
// Another work-around ... PHP doesn't seem to send the session cookie
// unless it is being currently created or regenerated
elseif (isset($_COOKIE[$this->_config['cookie_name']]) && $_COOKIE[$this->_config['cookie_name']] === session_id())
{
setcookie(
$this->_config['cookie_name'],
session_id(),
(empty($this->_config['cookie_lifetime']) ? 0 : time() + $this->_config['cookie_lifetime']),
$this->_config['cookie_path'],
$this->_config['cookie_domain'],
$this->_config['cookie_secure'],
TRUE
);
}
$this->_ci_init_vars();
log_message('info', "Session: Class initialized using '".$this->_driver."' driver.");
Above is the part of the Session.php file. I tried to add session_start(); on every function in the else statement as well as set_userdata function as people gave a solution but it didn't work. Session.php gets called from the construct file as below and then it makes a new session, which doesn't have UID. How would I be able to keep UID from the login part..?
public function __construct() {
parent::__construct();
$this->load->library('session'); --> this calls Session.php file
$this->load->model('member_model');
$this->load->model('setting_model');
$this->load->helper('iny_common_helper');
$this->load->helper('url');
if($this->session->userdata('uid')) {
$this->memberInfo = $this->member_model->get_member_infoByUid($this->session->userdata('uid'));
}
if($this->memberInfo->no) {
$this->member_model->memberInfo = $this->memberInfo;
}
I think you are under a slight confusion.
parent.location.reload() is a javascript construct that trigger the reload of the parent of the current window. In your case, it will trigger the reload of the login page, because you are not in an iframe embedded in a parent page, you are in a page, you have no parent.
You need to replace the code below with a redirect to the page that redirected to the login page (or the current home)
echo "<script>";
echo "parent.location.reload();";
echo "</script>";
You can use php or javascript.
php:
header('Location: https://example.com/');
javascript:
echo "<script>";
window.location.replace("https://example.com/");
echo "</script>";
I would use php :), in your case the else branch would become:
} else {
$userdata['uid'] = $result->uid;
$this->session->set_userdata($userdata);
header('Location: https://example.com/');
exit;
}
Do not forget tu replace the example.com with your correct url.
The exit (or die()) statement is important, should be present, also the header() function only works if it is the first output (no echo's, print's, etc before), otherwise you will need to use the javascript redirect.

PHP using exit() inside a function() to return only 1 value at a time

Suppose I have written the following function to check empty posted values:
function checkEmpty($postValue, $msg){
if($postValue == null){
return alert_danger($msg);
exit(); // NOT WORKING AS EXPECTED
}
}
And I am trying to call it for several input values this way:
echo checkEmpty($city, "City cannot be empty");
echo checkEmpty($phone, "phone cannot be empty");
echo checkEmpty($name, "name cannot be empty");
Now when I call this function above it echoes all the three values as it should be but I do not want that. I want it to return 1 error at a time. If city is empty it should return City cannot be empty only and not the others. When the user has corrected the error it should then proceed to check the next error. But it seems that the exit() used inside the function is not working as expected. I could use the following method:
if($name == null){
echo alert_danger("Please enter your Name.");
exit();
}
if($email == null){
echo alert_danger("Please enter your Email ID.");
exit();
}
if($phone == null){
echo alert_danger("Please enter your Phone number.");
exit();
}
But that makes the code too big unnecessarily if I have 15-20 variables to be checked. That's why I wanted to use the function method here as tried earlier. What should be the solution?
Use a function that echoes the error then dies after:
function checkEmpty($postValue, $msg){
if($postValue == null){
echo alert_danger($msg);
exit();
}
}
checkEmpty($city, "City cannot be empty"); //without echo

$_SESSION never getting set

I'm working on an assignment on a PHP course, and I'm stucked at the last part of it.
The assignment is to create a simple login form and use a session as well as hardcoded usernames and passwords (i.e. no db).
What I have problems with is the class that handles the login, and sessions especially. There's a lot of code and I didn't know what I could remove and therefore I've put it on Pastebin instead, hope that's alright.
Thing is that the unit tests that's built into the class passes except for nr. 4, the one that's checking that the user is logged in. The problem seems to be that $_SESSION[$this->loginSession] doesn't get set, and this is what I need help with.
The variable $loginSession is declared in the beginning of the class, and should be set to "isLoggedIn" when a user types a correct username and password, but that doesn't happen (no error message).
My class is:
<?php
class LoginHandler {
private $loginSession;
public function IsLoggedIn() {
if($_SESSION[$this->loginSession] == "isLoggedIn") {
return true;
}
else {
return false;
}
}
public function DoLogin($username, $password){
if ($username != null && $password != null){
switch ($username){
case "hello";
if ($password == "1234"){
$_SESSION[$this->loginSession] == "isLoggedIn";
return true;
}
else return false;
case "hello2";
if ($password == "12345"){
$_SESSION[$this->loginSession] == "isLoggedIn";
return true;
}
else return false;
}
}
else {
return false;
}
}
public function DoLogout(){
unset($_SESSION[$this->loginSession]);
}
public function Test() {
$this->DoLogout();
// Test 1: Check so you're not logged in.
if($this->IsLoggedIn() == true){
echo "Test 1 failed";
return false;
}
// Test 2: Check so that it's not possible to login with wrong password.
if ($this->DoLogin("hello", "4321") == true){
echo "Test 2 failed";
return false;
}
// Test 3: Check that it's possible to log in.
if ($this->DoLogin("hello", "1234") == false){
echo "Test 3 failed";
return false;
}
// Test 4: Check that you're logged in
if ($this->IsLoggedIn() == false){
echo "Test 4 failed";
return false;
}
return true;
}
}
?>
I hope it's enough to include the class and not all the other files, otherwise I'll put them up.
Now I see it :-)
$_SESSION[$this->loginSession] == "isLoggedIn";
== should be =
== compares while = sets
You need to start the session. session_start(); Place it at the very top of the documents (only one time on a page load) you are using.
$this->loginSession is never set so it's NULL
$_SESSION[null] is not possible as far as i know
change your code to
private $loginSession = 'testing';
and it should work
Why do you put semicolon in your case instruction case "hello";There should be a colon. case "hello": { ...instructions}

Warnin:Illegal offset type [CORE\Cake\Model\Model.php, line 2734] came on click of login in PHP

I created a simple login form using Cake Php.When i click on the Login button one Warning appear
Illegal offset type [CORE\Cake\Model\Model.php, line 2734
I have use link as a reference http://bakery.cakephp.org/articles/SeanCallan/2007/04/17/simple-form-authentication-in-1-2-x-x
Code of Login.ctp
Login
<?php echo $this->Form->create('User', array('action' => 'login'));?>
<?php echo $this->Form->input('username');?>
<?php echo $this->Form->input('password');?>
<?php echo $this->Form->submit('Login');?>
<?php echo $this->Form->end(); ?>
2. modal file
find(array('username' => $data['username'], 'password' => md5($data['password'])), array('id', 'username'));
if(empty($user) == false)
return $user['User'];
return false;
}
}
?>
3.controller file
<?php
App::uses('AppController', 'Controller');
class UsersController extends AppController
{
var $name = "Users";
var $helpers = array('Html', 'Form');
var $components = array("Auth");
function index()
{
}
function beforeFilter()
{
$this->__validateLoginStatus();
}
function login()
{
if(empty($this->data) == false)
{
if(($user = $this->User->validateLogin($this->data['User'])) == true)
{
$this->Session->write('User', $user);
$this->Session->setFlash('You\'ve successfully logged in.');
$this->redirect('index');
exit();
}
else
{
$this->Session->setFlash('Sorry, the information you\'ve entered is incorrect.');
exit();
}
}
}
function logout()
{
$this->Session->destroy('user');
$this->Session->setFlash('You\'ve successfully logged out.');
$this->redirect('login');
}
function __validateLoginStatus()
{
if($this->action != 'login' && $this->action != 'logout')
{
if($this->Session->check('User') == false)
{
$this->redirect('login');
$this->Session->setFlash('The URL you\'ve followed requires you login.');
}
}
}
}
?>
Why that happened.i am new in this.Some developers in PHP chat room suggest me to not use that Cake PHP. Any help is appreciated
Illegal offset type means that you tried to use an object or an array to index an array:
$x = stdClass;
$a = array(1,2,3,4);
$a[$x]; // illegal offset type
Check your code for possible places where you've taken user input (which could be an array of values even though you thought it's just one value) and used it in some function that expected just a value.
If that Cake internal function expected a value and tried to use it as the offset of an array, this message would appear.
Obs
The only place I notice in your code that passes a parameter (and not literal string values) is here:
$this->User->validateLogin($this->data['User']))
Do a var_dump on $this->data['User'] and see what's in it perhaps it's an array and you should've extracted just $this->data['User']['id'] I don't know, i haven't played that much with Cake.

cakephp session can't be written

Controller
function login() {
// Don't show the error message if no data has been submitted.
$this->set('error', false);
// Does not render the view
$this->autoRender = false;
// If a user has submitted form data:
if(!empty($this->data)) {
$someone = $this->Student->findByStudentEmail($this->data['Student']['email']);
if(!empty($someone['Student']['student_pwd']) && $someone['Student']['student_pwd'] == $this->data['Student']['password']) {
$this->Session->write('eyeColor', 'Green');
$this->Session->write('Student', $someone['Student']);
// session information to remember this user as 'logged-in'.
echo "success";
} else {
echo "failed";
}
}
function main(){
$this->set('students', $this->Student->find('all'));
$this->set('eyeColor', $this->Session->read('eyeColor'));
// Render the specified view
$this->render('/pages/main');
}
view
main.ctp
<?php print $eyeColor; ?>
<?php echo $session->read('eyeColor') ?>
It's in the manual: http://book.cakephp.org/view/1466/Methods
Admittedly, though, it's not very clear. Maybe I'll submit an update.

Categories