Перенаправление на страницу на основе пользовательских ролей в codeigniter - PullRequest
0 голосов
/ 04 ноября 2018

Я работаю над аутентификацией при входе пользователя с помощью codeigniter.

Сценарий входа отлично работает. У меня вопрос: когда пользователь вошел в систему, я хочу, чтобы он был перенаправлен на страницу, основанную на его пользовательских ролях

Роли, как показано ниже подписчик , admin , клиент , почтальон

User_model.php как показано ниже

class User_model extends CI_Model {

    public $status;
    public $roles;

    function __construct(){
        // Call the Model constructor
        parent::__construct();
        $this->status = $this->config->item('status');
        $this->roles = $this->config->item('roles');
    }

    public function insertUser($d)
    {
            $string = array(
                'firstname'=>$d['firstname'],
                'lastname'=>$d['lastname'],
                'phonenumber'=>$d['phonenumber'],
                'email'=>$d['email'],
                'roles'=>$this->roles[1],
                'status'=>$this->status[1],
                'password'=> '',
                'last_login'=> '',
                'created_at'=> '',
                'updated_at'=> ''
            );
            $q = $this->db->insert_string('users',$string);
            $this->db->query($q);
            return $this->db->insert_id();
    }

    public function isDuplicate($email)
    {
        $this->db->get_where('users', array('email' => $email), 1);
        return $this->db->affected_rows() > 0 ? TRUE : FALSE;
    }

    public function insertToken($user_id)
    {
        $token = substr(sha1(rand()), 0, 30);
        $date = date('Y-m-d');

        $string = array(
                'token'=> $token,
                'user_id'=>$user_id,
                'created'=>$date
            );
        $query = $this->db->insert_string('tokens',$string);
        $this->db->query($query);
        return $token . $user_id;

    }

    public function isTokenValid($token)
    {
       $tkn = substr($token,0,30);
       $uid = substr($token,30);

        $q = $this->db->get_where('tokens', array(
            'tokens.token' => $tkn,
            'tokens.user_id' => $uid), 1);

        if($this->db->affected_rows() > 0){
            $row = $q->row();

            $created = $row->created;
            $createdTS = strtotime($created);
            $today = date('Y-m-d');
            $todayTS = strtotime($today);

            if($createdTS != $todayTS){
                return false;
            }

            $user_info = $this->getUserInfo($row->user_id);
            return $user_info;

        }else{
            return false;
        }

    }

    public function getUserInfo($id)
    {
        $q = $this->db->get_where('users', array('id' => $id), 1);
        if($this->db->affected_rows() > 0){
            $row = $q->row();
            return $row;
        }else{
            error_log('no user found getUserInfo('.$id.')');
            return false;
        }
    }

    public function updateUserInfo($post)
    {
        $data = array(
               'password' => $post['password'],
               'last_login' => date('Y-m-d h:i:s A'),
               'created_at' => date('Y-m-d h:i:s A'),
               'updated_at' => date('Y-m-d h:i:s A'),
               'status' => $this->status[1]
            );
        $this->db->where('id', $post['user_id']);
        $this->db->update('users', $data);
        $success = $this->db->affected_rows();

        if(!$success){
            error_log('Unable to updateUserInfo('.$post['user_id'].')');
            return false;
        }

        $user_info = $this->getUserInfo($post['user_id']);
        return $user_info;
    }

    public function checkLogin($post)
    {
        $this->load->library('password');
        $this->db->select('*');
        $this->db->where('email', $post['email']);
        $query = $this->db->get('users');
        $userInfo = $query->row();

        if(!$this->password->validate_password($post['password'], $userInfo->password)){
            error_log('Unsuccessful login attempt('.$post['email'].')');
            return false;
        }

        $this->updateLoginTime($userInfo->id);

        unset($userInfo->password);
        return $userInfo;
    }

}

Основной код для контроллера показан ниже

defined('BASEPATH') OR exit('No direct script access allowed');

class Main extends CI_Controller {

        public $status;
        public $roles;

        function __construct(){
            parent::__construct();
            $this->load->model('User_model', 'user_model', TRUE);
            $this->load->library('form_validation');
            $this->form_validation->set_error_delimiters('<div class="error">', '</div>');
            $this->status = $this->config->item('status');
            $this->roles = $this->config->item('roles');
        }

    public function index()
    {

            if(empty($this->session->userdata['email'])){
                redirect(site_url().'main/login/');
            }

            /*front page*/
            $data = $this->session->userdata;
            $this->load->view('header');
            $this->load->view('index', $data);
            $this->load->view('footer');
    }



        public function login()
        {

            $this->form_validation->set_rules('email', 'Email', 'required|valid_email');
            $this->form_validation->set_rules('password', 'Password', 'required');

            if($this->form_validation->run() == FALSE) {
                $this->load->view('header');
                $this->load->view('login');
                $this->load->view('footer');
            }else{

                $post = $this->input->post();
                $clean = $this->security->xss_clean($post);

                $userInfo = $this->user_model->checkLogin($clean);

                if(!$userInfo){
                    $this->session->set_flashdata('flash_message', 'The login was unsucessful');
                    redirect(site_url().'main/login');
                }
                foreach($userInfo as $key=>$val){
                    $this->session->set_userdata($key, $val);
                }
                redirect(site_url().'main/');
            }

        }


        public function logout()
        {
            $this->session->sess_destroy();
            redirect(site_url().'main/login/');
        }


}

1 Ответ

0 голосов
/ 04 ноября 2018

Этот ответ может быть неправильным, поскольку он требует некоторых предположений.

Допущения:

  1. Существует только одна «роль» на пользователя
  2. Значение $userInfo->role представляет собой строку
  3. Контроллер, на которого вы хотите отправить авторизованного пользователя, это main
  4. Методы контроллера main называются так же, как и «роль», например. «подписчик», «админ», «клиент», «почтальон»

Если что-либо из перечисленного неверно, тогда этот ответ не сработает.

Вот мое предлагаемое решение. Я сделаю комментарии после этого кода.

public function login()
{
    $this->form_validation->set_rules('email', 'Email', 'required|valid_email');
    $this->form_validation->set_rules('password', 'Password', 'required');

    if($this->form_validation->run())
    {
        $post = $this->input->post();
        //$clean = $this->security->xss_clean($post);

        $userInfo = $this->user_model->checkLogin($post);

        if( ! $userInfo)
        {
            $this->session->set_flashdata('flash_message', 'The login was unsucessful');
            redirect('main/login');
        }

        $this->session->set_userdata($userInfo);
        redirect('main/'.$userInfo->roles);
    }

    $this->load->view('header');
    $this->load->view('login');
    $this->load->view('footer');
}

Вам, наверное, интересно, почему я все переставил. Ну, в основном потому, что это устраняет необходимость в else, чтобы идти с if. Меньше кода - это хорошо - верно?

Вызов redirect() завершает выполнение скрипта , означая, что любой код после redirect не будет выполняться. Потому что кодовый блок if($this->form_validation->run()){ заканчивается вызовом redirect, где заканчивается эта функция. Итак, вам не нужно else. В случае неудачного выполнения проверки перейдите прямо к представлению загрузки кода.

Ваш синтаксис для redirect неверен. redirect() создаст URL на основе значений вашего файла конфигурации. ( документы здесь ) Итак, убедитесь, что $config['base_url'] установлен правильно.

Ваш код

redirect(site_url().'main/');

должно быть написано

redirect('main/');

Вы, наверное, заметили, что я закомментировал строку

$clean = $this->security->xss_clean($post);

Большинство разработчиков будут утверждать, что предотвращение XSS должно быть сделано на выходе, а не на вводе. (Больше, чем вы хотите знать о предотвращении XSS ЗДЕСЬ .)

Поскольку входные данные используются для выбора записи в БД, кажется, что значения экранированы, и вы не сохраняете входные данные, поэтому опасности нет. Использование xss_clean() является ресурсоемким и бесполезным в этом случае.

Я удалил следующую петлю

foreach ($userInfo as $key => $val)
{
    $this->session->set_userdata($key, $val);
}

и изменил его на

$this->session->set_userdata($userInfo);

Если вы посмотрите на код set_userdata() и обнаружите, что он в значительной степени использует тот же код, который вы создали. (Код находится в /system/core/Session/Session.php вокруг строки 785.) Оставайтесь DRY и используйте набор инструментов платформы. set_userdata() примет ассоциативный массив и сделает то, что вам нужно.

Поскольку значение $userInfo->roles является строкой, которая соответствует имени метода, который вы хотите перенаправить на этот вызов, это поможет.

redirect('main/'.$userInfo->roles);

Если main не правильный контроллер, измените его выше. Если имена методов не соответствуют значениям роли, потребуется дополнительный код.

Надеюсь, это понятно и полезно.

...