Не могу разобраться с авторизацией в модуле.

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
Oleg-san
Сообщения: 40
Зарегистрирован: 2013.06.05, 22:23

Не могу разобраться с авторизацией в модуле.

Сообщение Oleg-san »

При реализации авторизации в модуле столкнулся с несколькими проблемами.

Имеется модуль (admin) созданный при помощи gii вход в который я хочу сделать только для авторизованных пользователей.
Для этого в AdminModule.php была слегка дополнена функция beforeControllerAction

Код: Выделить всё

public function beforeControllerAction($controller, $action)
{
if(parent::beforeControllerAction($controller, $action))
{
     $app = Yii::app();
     if($app->user->isGuest)
     {
          $app->user->setFlash('login', 'для выполнения этой операции вы должны пройти авторизацию');
          //$app->controller->redirect(array('login/login'));
          $app->controller->render('/login/login');
     }
     return true;
}
else
     return false;
}
Здесь все относительно понятно, если ты гость то показываем форму авторизации, а если авторизованный пользователь то показываем страницу. Но тут начинается первая проблема…
Код DefaultController.php:

Код: Выделить всё

class DefaultController extends Controller
{
    public $layout = 'main';

    public function actionIndex()
    {
        $this->render('/layouts/index');
    }

    public function actionLogin()
    {
        $model=new LoginForm;

        // collect user input data
        if(isset($_POST['LoginForm']))
        {
            $model->attributes=$_POST['LoginForm'];
            // validate user input and redirect to the previous page if valid
            if($model->validate() && $model->login())
                $this->redirect(Yii::app()->createUrl('admin/views/layouts/index'));
        }
        // display the login form
        $this->render('/login/login');
    }
}
Почему то не авторизованному пользователю в любом случае будет показана вьюшка login и index. Как исправить эту ошибку, иначе, зачем нужна авторизация, если любой посетитель сможет увидеть содержимое закрытой части сайта…

Следующая проблема… Если мы введем логин и пароль в форме и нажмем отправить то выскочить PHP предупреждение:
session_regenerate_id() [<a href='function.session-regenerate-id'>function.session-regenerate-id</a>]: Cannot regenerate session id - headers already sent
Исходник формы авторизации (login/login):

Код: Выделить всё

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'login-form',
    'enableClientValidation'=>true,
    'clientOptions'=>array(
        'validateOnSubmit'=>true,
    ),
    'htmlOptions' => array('class' => 'form-signin'),
    'action' => 'default/login',
));
    $model = new LoginForm;
?>
    <h2 class="form-signin-heading">Войти в панель</h2>
    <?php echo $form->textField($model,'username', array('class' => 'form-control', 'placeholder' => 'Логин')); ?>
    <?php echo $form->passwordField($model,'password', array('class' => 'form-control', 'placeholder' => 'Пароль')); ?>
    <?php echo CHtml::submitButton('Войти', array('class' => 'btn btn-large btn-primary btn-block')); ?>
<?php $this->endWidget(); ?>
Как исправить и эту ошибку?
Аватара пользователя
vova07
Сообщения: 1004
Зарегистрирован: 2012.11.29, 14:52
Откуда: Chisinau, Moldova

Re: Не могу разобраться с авторизацией в модуле.

Сообщение vova07 »

То что вы велосипедите, Yii уже умеет делать из коробки.
http://www.yiiframework.com/doc/api/1.1 ... les-detail
Смените подход и все получится.
Oleg-san
Сообщения: 40
Зарегистрирован: 2013.06.05, 22:23

Re: Не могу разобраться с авторизацией в модуле.

Сообщение Oleg-san »

Да действительно пытался сделать свой велосипед, когда в Yii уже это предусмотрено.
Добавил пару функций в DefaultController.php и все заработало.

Код: Выделить всё

public function filters()
{
    return array(
        'accessControl',
    );
}

public function accessRules()
{
    return array(
        array(
            'allow',
            'users' => array('@'),
        ),
        array(
            'deny',
            'users' => array('*'),
        )
    );
}
Ну как всегда появился новый вопрос. Как сделать, так что бы он отображал другую форму для авторизации. Сейчас он используют эту форму views/site/login, а я хочу что бы он использовал эту modules/admin/views/login/login?
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Не могу разобраться с авторизацией в модуле.

Сообщение slavcodev »

замени Yii::app()->user->loginUrl
Жду Yii 3!
Аватара пользователя
vova07
Сообщения: 1004
Зарегистрирован: 2012.11.29, 14:52
Откуда: Chisinau, Moldova

Re: Не могу разобраться с авторизацией в модуле.

Сообщение vova07 »

Думаю это вам поможет: http://www.yiiframework.com/doc/api/1.1 ... ack-detail
Извините, раньше открыл страницу видимо чем mc-bear.
UPD: То что я привел, годится для того случая когда у вас одна форма для авторизации на сайте, и другая для админки. (Я так просто понял задачу)
Если это не нужно, то mc-bear прав.
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Не могу разобраться с авторизацией в модуле.

Сообщение slavcodev »

Мое предложение навеяно мыслями, что у модуля админки должен быть система авторизации - WebUser, Identity и все что с этим связано.
Жду Yii 3!
Oleg-san
Сообщения: 40
Зарегистрирован: 2013.06.05, 22:23

Re: Не могу разобраться с авторизацией в модуле.

Сообщение Oleg-san »

Решил использовать deniedCallback.
Переписал малость контролер, теперь он выглядит таким образом:

Код: Выделить всё

class DefaultController extends Controller
{
    public $layout = 'main';

    public function actionIndex()
    {
        $this->render('/layouts/index');
    }

    public function filters()
    {
        return array(
            'accessControl',
        );
    }

    public function accessRules()
    {
        return array(
            array(
                'allow',
                'actions' => array('login'),
                'users' => array('?'),
                'deniedCallback' => Yii::app()->controller->render('/login/login'),
            ),
            array(
                'allow',
                'users' => array('@'),
            ),
            array(
                'deny',
                'users' => array('*'),
            )
        );
    }

    public function actionLogin()
    {
        $model=new LoginForm;

        // collect user input data
        if(isset($_POST['LoginForm']))
        {
            $model->attributes=$_POST['LoginForm'];
            // validate user input and redirect to the previous page if valid
            if($model->validate() && $model->login())
                $this->redirect(Yii::app()->createUrl('/layouts/index'));
        }
        // display the login form
        $this->render('/login/login');
    }
}
Все бы замечательно, но как всегда есть парочка но.
Если мы заходим на cайт.ру/admin то появляется форма авторизации все хорошо но всю картину портит сообщение с PHP ошибкой:
Cannot modify header information - headers already sent by (output started at Z:\home\yii.local\www\framework\web\CController.php:793)

Ну а если нам же удается авторизоваться то на странице админки отображается опять же сама форма и содержимое файла /layouts/index.
Oleg-san
Сообщения: 40
Зарегистрирован: 2013.06.05, 22:23

Re: Не могу разобраться с авторизацией в модуле.

Сообщение Oleg-san »

Ну все вопрос исчерпан, разобрался… Заменил loginUrl и все заработало)
Oleg-san
Сообщения: 40
Зарегистрирован: 2013.06.05, 22:23

Re: Не могу разобраться с авторизацией в модуле.

Сообщение Oleg-san »

Появился новый вопрос, касающийся авторизации в модуле.
А если быть точнее вопрос касается контроллеров и доступа к ним, которые находятся в модуле (modules/admin/controllers).

Если мы при помощи gii сгенерируем какой либо контролер с экшеном Index и поместим его в папку контролеров в модуле (modules/admin/controllers).
То любой посетитель зашедший на сайт и набравший в адресе sait.ru/admin/название_контролера/index получит доступ к результату работы экшена, но мне это не нужно, иначе какой смысл в админке…

Что бы не дать этому случиться то в контролер нужно добавить следующий код:

Код: Выделить всё

    public function filters()
    {
        return array(
            'accessControl',
        );
    }

    public function accessRules()
{
    return array(
        array(
            'allow',
            'actions' => array('login'),
            'users' => array('?'),
        ),
        array(
            'allow',
            'users' => array('@'),
        ),
        array(
            'deny',
            'users' => array('*'),
        )
    );
} 
В итоге я получу что и хотел, закрытую часть сайта в виде админки…

Но есть небольшое неудобство, если в админке будет много контролеров то в каждом из них прописывать фильтр мне кажется не рациональным.
Единственный выход который я вижу из этой ситуации это написать свой класс и прописать в нем фильтры на доступ а все контролеры будут наследоваться от этого класса. В итоге я получу что и хотел.

Хотелось бы узнать может, есть еще, какие либо варианты решения данной задачи. Или это единственный верный?
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Не могу разобраться с авторизацией в модуле.

Сообщение ElisDN »

Да-да. Сделайте AdminController c фильтром и наследуйте все контроллеры админки от него.
Аватара пользователя
greatdane
Сообщения: 408
Зарегистрирован: 2010.10.20, 14:05
Откуда: Электросталь
Контактная информация:

Re: Не могу разобраться с авторизацией в модуле.

Сообщение greatdane »

У меня вот так закрыта админка:

Код: Выделить всё

public function beforeControllerAction($controller, $action)
    {
        if(parent::beforeControllerAction($controller, $action))
        {
            // this method is called before any module controller action is performed
            // you may place customized code here
            if(Yii::app()->user->role!='admin' && Yii::app()->user->role!='manager')
            {
                if (Yii::app()->user->isGuest)
                {
                    Yii::app()->user->loginRequired();
                }
                else {
                    Yii::app()->request->redirect(Yii::app()->homeUrl);
                }
            }
            return true;
        }
        else
            return false;
    }
Таким образом в любой контроллер админки могут попасть только пользователи с ролью админ или менеджер. А доступ админу и манагерам уже разделяется фильтром внутри контроллеров.
Если RBAC не используется и пользователей как таковых нет, а админка нужна только для входа админа — можно вообще обойтись стандартным компонентом UserIdentity, а в функции выше заменить role на id.
Аватара пользователя
TranceSmile
Сообщения: 562
Зарегистрирован: 2011.06.27, 19:04
Откуда: Украина
Контактная информация:

Re: Не могу разобраться с авторизацией в модуле.

Сообщение TranceSmile »

а создать операцию для доступа в админ панель или админа унаследовать от менеджера. Выше это говнокод, имхо
Изображение
Ответить