I want to make some actions available only for logged in users.
I've tried to restrict some by this code:
function _remap($method)
{
$restricted = array('update_rating', 'delete_post');
if( ! $this->session->userdata('logged_in') && in_array($method, $restricted))
{
echo 'Log in, please';
}
else {
$this->$method();
}
}
But $this->$method() didn't receive parameters which was sent in url. What to do?
I want to make some actions avalible only for logged in users.
To restrict logged in users for an entire controller use something like:
function __construct(){
if(!is_logged_in){
redirect('user/login');
}
}
Or do the same if you need to restrict a specific method:
function restricted_function(){
if(!is_logged_in){
redirect('user/login');
}
}
This requires that you have an is_logged_in variable set before the controller is called.
I use a a MY_controller that checks for a logged in session that all controllers inherit.
Ideally you should not be using this patter of development for creating a user login. You should simply do the check in the constructor of the class that you're calling, and use $this->router->method to see what method the user is trying to access. Check that against an array of methods that require login, then check to see if the user is logged in or not. If one of the conditions is false, redirect to login page, or else, continue with execution of the call. Sample implementation below:
Class XYZ extends Controller{
function __construct() {
parent::controller();
$protected_methods = array('method_1', 'method_2');
if(in_array($this->router->method, $protected_methods)){
// check if user is logged in
if(!$this->session->userdata('logged_in'))
redirect('/login');
}
}
}
You didn't send any parameters to it.
You should give all the parameters you need the $method to evaluate.
function _remap($method)
{
$restricted = array('update_rating', 'delete_post');
if( ! $this->session->userdata('logged_in') && in_array($method, $restricted))
{
echo 'Log in, please';
}
else
{
$params = get_func_get_args();
$this->$method($params);
}
}
Note that the methods would now receive and array of the parameters.
Related
I make an online store in which I have two login places. /checkout (in cart) and /login.
Can i do it in the existing method to make redirect look like this?
if i login in /checkout ->redirect('/checkout').
(for loggin in /login) it stays like it is /redirect('/')
I would solve that by using the redirectTo() method in the Login Controller and checking which route is sending the request through the path() method. You have to name the routes for it to work though. So in your login Controller you'll have this;
use Illuminate\Support\Facades\Route;
protected function redirectTo(){
if(Route::currentRouteName() == 'login'){
return '/';
}else if(Route::currentRouteName() == 'checkout'){
return '/checkout';
}
}
more info on how to get the route name here
and info on the redirectTo() function here
Try it out, tell me what happens..
only this solution works:
protected function redirectTo() {
if(strpos(URL::previous(), 'checkout')) {
return '/checkout';
} elseif(strpos(URL::previous(), 'login')) {
return '/';
}
}
I'm trying to create a global authentication using _remap method in Codeigniter. Here are the website conditions for accessing the controller/method:
Method must be exist.
Some controllers can only be accessed if the user/admin have logged in.
Some controllers can only be accessed only by admin.
The _remap method is written in MY_Controller which will be inheritated to all the controller. Here is my code:
protected $must_login;
protected $must_admin;
public function _remap($method, $param = array())
{
# Check if method exist
if (method_exists($this, $method))
{
# Check whether the user has to be login to access it
if ($this->must_login)
{
# Check whether the user has logged in
if ($this->auth->is_loggedin())
{
# Check whether it has to be admin to access it
if ($this->must_admin)
{
# Check whether it is admin
if ($this->auth->is_admin())
{
# Run the method
return call_user_func_array(array($this, $method), $param);
}
else
{
# Redirecting to login form
$this->go('auth');
}
}
else
{
return call_user_func_array(array($this, $method), $param);
}
}
else
{
$this->go('auth');
}
}
else
{
return call_user_func_array(array($this, $method), $param);
}
}
else
{
$this->go('auth');
}
}
The code is working but i feel like it can be simplified. I have tried but it always end up in infinite redirect. Is there any way to simply this method?
Thank you in advance.
my preference is usually to put the check right in the constructor, and then return the user or admin with $this->
function __construct()
{
parent::__construct();
if (!$this->user = $this->users->returnUser())
{
redirect("userlogin");
}
}
Then $this->user is now available for everything that your controller calls - models and views:
echo 'Hello ' . $this->user->first_name . ' ' . $this->user->last_name ;
so then lets say you have Admins and a Superadmin. You don't have to check - does this admin have access to this controller? You can just use separate checks in each controller constructor:
if (!$this->admin = $this->admins->returnAdmin())
{
redirect("adminlogin");
}
// Or
if (!$this->superAdmin = $this->superadmins->returnSuperAdmin())
{
redirect("superadminlogin");
}
This also cleanly separates out where you are redirecting to so they can go to the correct login page. Finally it gives you a quick heads up when you are looking at the controller code - at the top of the page you will immediately know what kind of user should have access to it. Something to consider - would strongly encourage you not to check for login or admin status in your view files. Its much safer to create a few more view files. Your view files should not have the responsibility of determining whether someone is logged in or not. So basically once you have determined what the viewers status is in the constructor - thats it, you don't need to check again until the next controller call.
I am working on codeigniter. I am implementing signin functionality and when user signs in i call this controller
function validate_credentials()
{
$this->load->model('membership_model');
$query = $this->membership_model->validate();
if($query==1)
{
$data = array
(
'username'=>$this->input->post('username'),
'is_logged_in' => true
);
$email=$data['username'];
$this->session->set_userdata('email_of_user',$email);
$this->load->model('search_peoplee');
$data['userid']= $this->search_peoplee->get_userid_from_email($email);
foreach ($data['userid'] as $row)
{
$one=$row->userid;
}
$data['result']=$this->membership_model->friend_notify($one);
$data['count']=$this->search_peoplee->get_friends_count($one);
$this->load->model('search_peoplee');
$data['values']= $this->search_peoplee->get_notifications($one);
$data['count_notify']=$this->search_peoplee->get_notifications_count($one);
$this->session->set_userdata('lookatit','no');
$this->load->view('home_screen',$data);
}
elseif($query==2)
{
$data['main_content']='email_not_found';
$this->load->view('includes/template',$data);
}
else
{
$this->error_index();
}
}
this validates the credentials and stores a session, this controller calls a model "$this->membership_model->validate();" which picks the value form view and check that if user exists, the problem is when i retype the address it takes me to the login page and says sign in again as the model reads empty values. How to avoid this. help!!!
after you have authenticated, how about setting a session variable.
so,
$this->session->set_userdata('authenticated',TRUE);
then in the controller, first check if the user is authenticated and do a redirect, otherwise go to the validate_credentials method ??
How do I change the content for a user when he logs in? I mean like enabling voting, changing "login" to "logout" etc.
What I think to do is to start the session when user logs in (I am preferring to start session only when user logs in, not all the time). Then add data to the session's cookie like-
//controller
$moredata = array(
'username' => $this->username,
'login' => TRUE
);
$this->session->set_userdata($modedata);
//redirect
Then in the other controller, where he has been redirected I check the following-
$login = $this->session->userdata('login');
if ($login==TRUE)
Depending on the 'if' condition I will pass a variable to the view, with the help of that variable I will forward only the div/sections which should be shown to a logged-in user.
The problem is, while performing the above comparison Codeigniter shows following error (remember I haven't added 'session' in autoload array yet)
Message: Undefined property: NameOfController::$session
And If I set following in the autoload file
$autoload['libraries'] = array('session');
then the "if ($login==TRUE)" comparison always shows FALSE.
What should I do?
If I were you, I'd place all your session checks in a base controller which all your other main controllers extend. This allows you to keep things DRY:
class BaseController extends CI_Controller {
public function __construct()
{
parent::__construct();
}
public function isLoggedIn()
{
// Will return true or false
return $this->session->userdata('login');
}
}
And in one of your functional controllers (the example below handles users):
class UserController extends BaseController {
public function __construct()
{
parent::__construct();
}
public function profile()
{
// Redirect if not logged in
if (!$this->isLoggedIn()) {
$this->redirect('some/other/page')
}
}
public function register()
{
// Show different HTML if not logged in
$data = array(
'isLoggedIn' => $this->isLoggedIn()
);
$this->load->view('register', $data);
}
}
The second method in UserController allows you to render different content in your view:
<? if ($isLoggedIn): ?>
<p>You're logged in!</p>
<? else: ?>
<p>Not logged in</p>
<? endif; ?>
On my last project we created a simple permissions helper that had functions to check for logged-in status and for privilege levels. Then we'd just call the helper's functions as needed from anywhere in the system. If the user is logged in and has privs for that content then they get the content - otherwise we'd redirect them to a registration or other error page. Since all of that logic is in the helper functions, we could wrap any permission-requiring code in a quick permissions call like if(is_logged_in()){code requiring login to access}.
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"...?