#codeigniter
#codeigniter
Вопрос:
У меня есть контроллер, который отображает раздел моего сайта, и все страницы внутри него (методы) должны отображаться только в том случае, если пользователь вошел в систему. В противном случае они должны быть перенаправлены обратно на экран входа в систему.
Чтобы заставить это работать, я только что сделал это:
function index() {
if ($this->session->userdata('logged_in')) {
$this->load->view('main');
} else {
redirect('/login');
}
}
function archive() {
if ($this->session->userdata('logged_in')) {
и так далее… повторяем эту проверку в каждом методе. Какой самый простой способ выполнить эту проверку один раз для нескольких методов или всех методов в контроллере?
Комментарии:
1. я советую вам использовать библиотеку для пользовательского процесса. Aauth подходит для этого. github.com/emreakay/CodeIgniter-Aauth
Ответ №1:
Вы можете запускать код в каждом методе контроллера, запустив его в __construct()
методе:
function __construct()
{
parent::__construct();
if ( ! $this->session->userdata('logged_in'))
{
// Allow some methods?
$allowed = array(
'some_method_in_this_controller',
'other_method_in_this_controller',
);
if ( ! in_array($this->router->fetch_method(), $allowed)
{
redirect('login');
}
}
}
Вы можете удалить «разрешенные» биты, если хотите ограничить доступ ко всему, но есть способы сделать это получше, например, создать базовый контроллер:
// Create file application/core/MY_Controller.php
class Auth_Controller extends CI_Controller {
function __construct()
{
parent::__construct();
if ( ! $this->session->userdata('logged_in'))
{
redirect('login');
}
}
}
Затем расширьте свои ограниченные контроллеры Auth_Controller
вместо CI_Controller
. Теперь ваш код будет запускаться при каждой загрузке контроллера.
Дополнительная информация о расширении основных классов: http://www.codeigniter.com/user_guide/general/core_classes.html#extending-core-class
Также представляет интерес: http://php.net/manual/en/language.oop5.decon.php
Комментарии:
1. Для
redirect()
работы необходимо загрузить помощник URL:$this->load->helper('url');
2. Вы назвали файл вашего нового контроллера MY_Controller.php , тем не менее, вы назвали класс Auth_Controller. Это не должно сработать, верно? Я спрашиваю, потому что столкнулся с чем-то очень странным: пока я называл свой новый контроллер (который расширяет базовый контроллер) MY_Auth_Controller и пытался использовать это в качестве базового класса моих контроллеров, CodeIgniter продолжал сбоить. Когда я назвал if просто ‘MY_Controller’, все сработало хорошо. Почему это?
3. @whage Именно так был создан CI, он загрузится автоматически MY_Controller.php если оно существует.
4. Я использую CI версии 3.0.0. Я попробовал приведенный выше код (# 2, MY_Controller), и я получаю пустую страницу, без html. Я заметил, что на этой странице написано сохранить MY_Controller в application / libraries /. В любом случае, я не получаю никакой любви!
5. @GregoryLewis для codeigniter 3 вы можете использовать мой ответ ниже.
Ответ №2:
Для CodeIgniter 3 я изменил ответ Уэсли Марча на это
// Создать файл application/core/MY_Controller.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class MY_Controller extends CI_Controller {
function __construct()
{
parent::__construct();
$CI = amp; get_instance();
$CI->load->library('session');
$CI->load->helper('url');
if ( !$this->session->userdata('logged_in'))
{
redirect('login');
}
}
}
Затем в любом контроллере для проверки авторизации я использовал
новости класса расширяют MY_Controller { //код здесь }
Если вы используете модули и разные сеансы для пользователей веб-сайта и администраторов, вы можете использовать этот код, чтобы идеально перенаправлять их на разные страницы входа-
function __construct() {
parent::__construct();
$CI = amp; get_instance();
$CI->load->library('session');
$CI->load->helper('url');
// echo "<pre>";print_r($this->router);echo "</pre>";
/**
* if webmaster then check admin session else check user session
* But there may be some classes's method that doesn't requires login hence it is also need to check if
* current request is for those methods before checking session
*/
//to use $this->config->item('webmaster_name') this you have to define
// $config['webmaster_name'] = "webmaster"; in config.php file
if ($this->router->module == $this->config->item('webmaster_name')) {
if (!$this->session->userdata('admin')['id']) {
redirect($this->config->item('webmaster_name').'/login');
}
} else {
if (!$this->session->userdata('user')['id']) {
redirect('login');
}
}
}
Если вы также хотите, чтобы пользователям разрешался доступ к некоторым методам с любого конкретного контроллера без входа в систему, вы можете использовать этот код —
function __construct() {
parent::__construct();
$CI = amp; get_instance();
$CI->load->library('session');
$CI->load->helper('url');
//echo "<pre>"; print_r($this->router);echo "</pre>"; //_pr($this->config->item('excluded_auth'));
/**
* if webmaster then check admin session else check user session
* But there may be some classes's method that doesn't requires login hence it is also need to check if
* current request is for those methods before checking session
*/
if ($this->router->module == $this->config->item('webmaster_name')) {
if (!$this->session->userdata('admin')['id']) {
redirect($this->config->item('webmaster_name') . '/login');
}
} else {
if (array_key_exists($this->router->class, $this->config->item('exclude_auth')) amp;amp; in_array($this->router->method, $this->config->item('exclude_auth')[$this->router->class])) {
//echo "escape this method. don not validate for a session";
} else {
if (!$this->session->userdata('user')['id']) {
redirect('login');
}
}
}
}
Примечание: Вы можете определить пользовательский конфигурационный файл для определения ваших исключенных методов, например-
//save file in application/config/without_auth_methods.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
$config['exclude_auth']['news'] = array('index', 'view');
$config['exclude_auth']['users'] = array('index');
Комментарии:
1. Спасибо! Очень хорошо объяснено!
Ответ №3:
Я использую эту функцию:
Затем просто вызовите $this-> isAuthorized из ваших контроллеров __construct.
Это позволяет мне контролировать, к каким контроллерам осуществляется доступ, и к каким методам также осуществляется доступ.
protected function isAuthorized()
{
switch ( strtolower( $this->router->class ) )
{
case 'pages':
$disallowLoggedOut = array( 'dashboard' );
$disallowLoggedIn = array( 'index' );
break;
case 'users':
$disallowLoggedOut = array( 'logout' );
$disallowLoggedIn = array( 'register', 'login' );
break;
}
if ( $this->session->userdata( 'loggedIn' ) )
{
if ( in_array( $this->router->method, $disallowLoggedIn ) )
{
redirect( 'pages/dashboard' );
}
}
else
{
if ( in_array( $this->router->method, $disallowLoggedOut ) )
{
redirect( 'pages/index' );
}
}
}
Ответ №4:
Лучший способ решить такую проблему — создать пользовательский помощник, который должен вызываться в каждом методе класса контроллера, например, перейдите в application / helpers и создайте файл login_helper.php Вставьте следующий код во вспомогательный
<?php
defined('BASEPATH') OR exit('no direct access');
function isLogin($sessionType)
{
if(empty($_SESSION[$sessionType]))
redirect(base_url('loginURL'));
}
?>
Теперь загрузите этот помощник в конструктор контроллера.
application/controllers/Access.php
таким образом
defined('BASEPATH') OR exit('access denied');
class Access Extends CI_Controller
{
funcrion __construct()
{
parent::__construct();
$this->load->helper('login');
}
function home()
{
isLogin();
$this->load->view('home_page);
}
}