Admin access with Codeigniter - php

I have created a log in form for my admin pages and it works, but for now everyone who logs in can access those pages.
My users are also belong to usergroups and my users table in the database has a group_id column. The admin group has an id of 1.
What I'd like to do is that if someone who belongs to the admin group logs in can access the admin pages, but if the user belongs to a different group and tries to log in be redirected to main page or anywhere.
What I'm trying to do is add a similar code to the admin pages controllers
class Dashboard extends MY_Controller {
public function __construct() {
parent::__construct();
// Access control
if(!$this->session->userdata('logged_in')) {
redirect('admin/login');
}
}
}
My model
class Authenticate_model extends CI_Model {
public function login_user($username, $password){
//Secure password
$enc_password = md5($password);
//Validate
$this->db->where('username',$username);
$this->db->where('password',$enc_password);
$result = $this->db->get('users');
if($result->num_rows() == 1){
return $result->row();
} else {
return false;
}
}
}

You can do it yourself, provide validation and set $SESSION variable to retrieve if the user is logged in. But this is too much work, and error prone.
I recommend you to use this popular library: https://github.com/benedmunds/CodeIgniter-Ion-Auth. It is really easy to set up, you just need to copy some files and you are ready to go.

If you really want to do it your self(thats the question) then you need to store in SESSION two variables - logged_in and is_admin.
I would recomend two create library with function:
function is_logged_in($admin = FALSE){
$is_logged = $this->session->userdata('logged_in');
if($admin){
$is_logged = $this->session->userdata('is_admin')
}
return $is_logged;
}
This assumes that you store two booleans "logged_in" and "is_admin" in SESSION.(If user has group_id = 1 then you would store TRUE in is_admin)
Then you can protect your site members only pages
if(!$this->your_authenticatation_library->is_logged_in()){redirect('notMembersControler')}
and admin page:
if(!$this->your_authenticatation_library->is_logged_in(TRUE)){redirect('notMembersControler')}
Thats the basic idea, you need to work around depending on what you are up to. Hope this helps!

Related

Laravel logging System User fails

Im trying to log in a system user without sessions or cookies.
The following code in my middelware works unless the user id is from a system user:
$interface_token = $request->header('token');
if ($interface_token !== 'my_secret') {
return response('Unauthorized', 401);
}
$user_id = 1; // Just for testing. Here I want to login a system user.
$success = Auth::onceUsingId($user_id);
if (!$success)
{
throw new Exception('failed!');
}
I want to log in a system user since this specific routes are going to be call from an internal service not from a "real" user.
If I update the table users setting system_user = 0 of user id 1, it works.
If system_user = 1 then it doesn't authenticate.
This system_user column is just a tinyint added to the user's table that shouldn't affect but apparently it does.
The user model is using the SystemUserTrait.
Any ideas?
I'm using Laravel 5.4
Edit
The SystemUserTrait is adding a global scope which does the following:
public function apply(Builder $builder, Model $model)
{
$builder->where('system_user', '=', 0);
}
So that's why it was not working with the user system. But now the question is if is possible to disable this to authenticate the user.
I tried the following without success:
$user = User::withoutGlobalScope(SystemUser::class)->find(1);
$success = Auth::login($user);
The user is fetched but the login fails anyway.
Is there a way to avoid using the global scope for a function?
The solution was to fetch the user with User::withoutGlobalScope and then to use Auth::setUser function to avoid queries which used the scope.
$interface_token = $request->header('token');
if ($interface_token !== 'my_secret') {
return response('Unauthorized', 401);
}
$user = User::withoutGlobalScope(SystemUser::class)->find(1);
Auth::setUser($user);

cannot access object user from another php page

I'm trying to learn MVC pattern but,even if I'm trying hard, it seems I still got big issues.
I have got a controller,named baseController that do the following:
class baseController {
public $model;
public $user;
...
$activeuser = $this->model->getlogin();
if ($activeuser != 'invalid user' && $activeuser != "") {
$this->user=$activeuser;
header("Location:home.php");
}
I have got a model.php file which contains the getlogin() function:
public function getlogin() {
if (isset($_REQUEST['username']) && isset($_REQUEST['password'])) {
$username = mysql_real_escape_string($_REQUEST['username']);
$pwd = mysql_real_escape_string($_REQUEST['password']);
$pwd = md5($pwd);
$query = mysql_query("SELECT * FROM users WHERE username='$username' AND password ='$pwd' AND attivato =1;");
if (mysql_num_rows($query) == 1) {
require_once 'User.php';
$sql=mysql_fetch_array($query);
$activeuser = new User();
$activeuser->username=$sql['username'];
$activeuser->email=$sql['email'];
return $activeuser;
} else {
return 'invalid user'; //TO-DO
}
}
}
The home.php create a new homeController and calls its invoke() function.The homeController file include the view page,that's called afterlogin.php.
In the afterlogin.php I've got the "ERROR":
if (isset($activeuser)){
echo "<p>Utente ".$activeuser->username."</p>";
echo "<p>Email ".$activeuser->email."</p>";}
//echo "<p>Pass ".$activeuser->pwd."</p>";
echo"<h1> HOMEPAGE, LOGIN OK </h1>";
It seems the homeController,and so the afterlogin page cannot access the user created in the baseController file. If I try an echo inside the baseController of $this->user->username everything is working. What should I do?? HELP!!
The client-server lifecycle is effectively stateless; on every page load, your variables and objects are wiped out.
There are the client-sourced $_POST and $_GET superglobals, which is part of the standard form submission and url query processes.
The server has databases, file writing (sketchy from a security POV) and the $_SESSION superglobal. These are the ways the server can manage a data state between pageloads.
Understand that if you're using objects, you need to have them instantiated on every page load for them to work. You can store your user_ID in $_SESSION['user_ID'] and instantiate the user object from it every time, making appropriate changes according to how the data changes.

ignoring frontpage.php in codeigniter

I'm currently working on an existing website created in codeigniter.
Whenever a user enters a page, he gets redirected to frontpage.php, that checks if the user is logged in, if not he gets redirected to the login page.
Now, I have one page where this frontpage.php shouldnt be executed, and any user can enter it.
Any help is greatly appreciated.
Had a similar problem and solved it this way by using some online tutorials
1: Make a seperate loginpage (ex login.php) prior to the 'frontpage.php'.
2: Pass the login, password and a session variable to the frontpage.
3: Recode you 'frontpage.php' to check for the session variable passed by 'login.php'.
If u entered the page trough the normal way it will use the normal login.
if u entered the page trough the new 'login.php' page it will be picked up by the recoded 'frontpage.php' and bypass the normal way.
Hope this helps
Grtz
Re-route everything to your pages controller and use this as your default
$route['default_controller'] = 'pages';
$route['(.*)'] = 'pages/index/$1';
-
class Pages extends CI_Controller
{
protected $currentUser = null;
public function __construct()
{
parent::__construct();
$this->currentUser = Auth::getCurrentUserObject(); //check user is logged in
}
public function index($uri='home')
{
$sizeOfSegments = sizeof($this->uri->rsegments);
if ($sizeOfSegments >= 3)
{
$uri = $this->uri->rsegments[3];
}
else
{
$uri = 'home';
}
$pageFound = Page::find($uri); //query the database
if (!$pageFound)
{
return show_404($uri); // find out where there were headed
}
unset($sizeOfSegments, $uri);
if(is_null($this->currentUser) OR !$this->currentUserHasPermissionToViewThisPage OR !$pageIsNotPublic)
{
return redirect('login');
}
$this->load->view();
}
}
make new controller
class Newpage extends CI_Controller {
public function index(){
$this->load->view('newpage');
}
}
now goto
yourhost.com/index.php/newpage
May be your default Controller have a coding of checking whether user is logged or not. Please remove or change the code in controller.
I think you need to delete the controller, it works like that!

Checking the database and redirectering to the particular page

If the admin login checked is correct it should redirect to dashboard page, but if admin login is correct or incorrect it is going to dashboard page. If it is incorrect it should go to login page.
Here is the code
<?php
class Validate extends CI_Model
{
public function checkdatabase()
{
$username=$_POST['username'];
$password=$_POST['password'];
//echo $username;
$this->load->database();
$query ="select * from adminlogin where name='$username' AND password='$password'";
$value = $this->db->query($query);
$data = $value->result();
return $data;
}
}
?>
Here is the condition in the controller
if($value=$this->validate->checkdatabase()){
redirect('dashboard', 'refresh');
}else{
$this->load->view('admin/login');
}
There really is a fair bit wrong with the way you're doing things, first and foremost in my mind is you're not auto-loading the database library, with just about any CI site you're going to be using that library so often it makes no sense not to have it auto-loading.
Next, as others have said you're not sanitizing the input at all leaving yourself open for injection, and considering it's a login you've left that completely wide open. CI's input wrapper handles that for you, see in the code below.
You're also not checking to see what the return value is, and with logins you always check for a single return.
<?php
class Validate extends CI_Model
{
public function checkdatabase()
{
$username=$this->input->post('username');
$password=$this->input->post('password'); //and honestly this is taking a plain text password... not a good thing.
//echo $username;
$this->load->database(); //again, do this in the autoload.php
$query ="select * from adminlogin where name='$username' AND password='$password'";
$value = $this->db->query($query);
if($value->num_rows()==1)
{
$data = $value->result();
return $data;
} else {
return false;
}
}
I see after typing this that you've got it working, there are still valid points here you should take into consideration so I'll post it anyway.
You can try following
`
$value=$this->validate->checkdatabase();
if(isset($value)){
redirect('dashboard', 'refresh');
}else{
$this->load->view('admin/login');
}
`
# My Code Programs

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