Authorization - uniqcle/Yii2 GitHub Wiki

3 процедуры взаимосвязаны:

  • Сначала определяют имя (логин или номер) – идентификация
  • Затем проверяют пароль (ключ или отпечаток пальца) – аутентификация
  • И в конце предоставляют доступ – авторизация

Подробно: Идентификация, аутентификация, авторизация

Вход на сайт

- username // Идентификация
- password // Аутентификация

Логин:

1) Ввод данных в форму, отправить
2) Загрузка данных в модель
3) Валидиация
   3.1 Используя username, найти запись в БД
   3.2 Сверить пароль в записи БД и пароль из формы
4) Запомнить пользователя

Контроллер frontend\controllers\UserController.php

namespace frontend\controllers;

use Yii; 
use frontend\models\forms\SignupForm; 
use frontend\models\forms\LoginForm; 

class UserController extends \yii\web\Controller
{
	//Register
	public function actionSignup()
    {	
    	$model = new SignupForm(); 

    	if($model->load( Yii::$app->request->post() ) && $model->save() ){

    		Yii::$app->session->setFlash('success', 'New user added!'); 

    		return $this->redirect(['site/index']); 
    	}

        return $this->render('signup', [
        	'model' => $model
        ]);
    }

    //LogIn
    public function actionLogin()
    {

    	$model = new LoginForm();

    	if( $model->load( Yii::$app->request->post() ) && $model->login() ){

    		return $this->redirect(['site/index']); 

    	} 

        return $this->render('login', [
        	'model' => $model
        ]);
    }

    //LogOut
    public function actionLogout(){

    	Yii::$app->user->logout(); 

    	return $this->redirect(['site/index']); 
    }
}

Модель frontend\models\forms\LoginForm.php

namespace frontend\models\forms; 

use Yii; 
use yii\base\Model; 
use frontend\models\User; 

class LoginForm extends Model 
{
	public $username; 
	public $password; 

	
	public function rules(){
		return [
			['username', 'trim'], 
			['username', 'required'], 
            ['password', 'required'], 
            ['password', 'validatePassword']
		]; 
	}

	public function login(){

		if( $this->validate() ){
			//Находим пользователя по его username
			$user = User::findUserByName($this->username); 
			//Скармливаем пользователя компоненту user
			return Yii::$app->user->login($user); 
		}

		return false; 
	}

	//Собственные валидаторы ничего не должны возвращать. Единственное в случае ошибки - вызывать метод addError() в случае ошибки.
	public function validatePassword($attribute, $params){
		//Находим пользователя по username
		$user = User::findUserByName($this->username); 
		//Если полльзователь есть
		if( $user ){
			//Сверяем пароли в модели user. 
			if( !$user->validatePassword($this->password) ){
				$this->addError($attribute, 'Неверный пароль'); 
			} 
		}
 
	}
}

Модель frontend\models\User.php

namespace frontend\models;

use Yii;
use yii\web\IdentityInterface; 

/**
 * This is the model class for table "user".
 *
 * @property int $id
 * @property string $username
 * @property string $auth_key
 * @property string $password_hash
 * @property string $password_reset_token
 * @property string $email
 * @property int $status
 * @property int $created_at
 * @property int $updated_at
 */
class User extends \yii\db\ActiveRecord implements IdentityInterface 
{

    public static function tableName()
    {
        return 'user';
    }


    public function rules()
    {
        return [
            [['username', 'auth_key', 'password_hash', 'email', 'created_at', 'updated_at'], 'required'],
            [['status', 'created_at', 'updated_at'], 'integer'],
            [['username', 'password_hash', 'password_reset_token', 'email'], 'string', 'max' => 255],
            [['auth_key'], 'string', 'max' => 32],
            [['username'], 'unique'],
            [['email'], 'unique'],
            [['password_reset_token'], 'unique'],
        ];
    }


    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'username' => 'Username',
            'auth_key' => 'Auth Key',
            'password_hash' => 'Password Hash',
            'password_reset_token' => 'Password Reset Token',
            'email' => 'Email',
            'status' => 'Status',
            'created_at' => 'Created At',
            'updated_at' => 'Updated At',
        ];
    }


    public static function findUserByName($username){

        return self::find()->where(['username' => $username])->one();
    }

    //Валидация пароля пользователя
    public function validatePassword( $password ){
       // if( Yii::$app->security->validatePassword( $password, $this->password_hash ) === false ) 
       // или так
       return Yii::$app->security->validatePassword( $password, $this->password_hash ); 
    }





    //IDENTITY INTERFACE
    public static function findIdentity($id)
    {
        return static::findOne($id);
    }

    /**
     * Finds an identity by the given token.
     *
     * @param string $token the token to be looked for
     * @return IdentityInterface|null the identity object that matches the given token.
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        return static::findOne(['access_token' => $token]);
    }

    /**
     * @return int|string current user ID
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return string current user auth key
     */
    public function getAuthKey()
    {
        return $this->auth_key;
    }

    /**
     * @param string $authKey
     * @return bool if auth key is valid for current user
     */
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }
}

Вью frontend\views\user\login.php

/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \frontend\models\LoginForm */
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
$this->title = 'Login User';
$this->params['breadcrumbs'][] = $this->title;
?>

<div class="site-signup">
    <h1><?= Html::encode($this->title) ?></h1>

    <p>Please fill out the following fields to login:</p>

    <div class="row">
        <div class="col-lg-5">
            <?php $form = ActiveForm::begin(['id' => 'form-signup']); ?>

                <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>

                <?= $form->field($model, 'password')->passwordInput() ?>

                <div class="form-group">
                    <?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
                </div>

            <?php ActiveForm::end(); ?>
        </div>
    </div>
</div>

Настройки frontend\config\main.php

...
        'user' => [
            //Указываем класс в качестве Identity
            'identityClass' => 'frontend\models\User',
            'enableAutoLogin' => true,
            'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
        ],
...

Настройки меню frontend\views\layouts\main.php

...
    <?php
    NavBar::begin([
        'brandLabel' => Yii::$app->name,
        'brandUrl' => Yii::$app->homeUrl,
        'options' => [
            'class' => 'navbar-inverse navbar-fixed-top',
        ],
    ]);
    $menuItems = [
        ['label' => 'Home', 'url' => ['/site/index']],
        ['label' => 'Authors', 'url' => ['/lib/author/index']],
        ['label' => 'Publisher', 'url' => ['/lib/publisher/index']],
        ['label' => 'About', 'url' => ['/site/about']],
        ['label' => 'Contact', 'url' => ['/site/contact']],
    ];
    if (Yii::$app->user->isGuest) {
        $menuItems[] = ['label' => 'Signup', 'url' => ['/user/signup']];
        $menuItems[] = ['label' => 'Login', 'url' => ['/user/login']];
    } else {
        $menuItems[] = '<li>'
            . Html::beginForm(['/user/logout'], 'post')
            . Html::submitButton(
                'Logout (' . Yii::$app->user->identity->username . ')',
                ['class' => 'btn btn-link logout']
            )
            . Html::endForm()
            . '</li>';
    }
    echo Nav::widget([
        'options' => ['class' => 'navbar-nav navbar-right'],
        'items' => $menuItems,
    ]);
    NavBar::end();
    ?>
...

Вывод в любом View

...
      //var_dump( Yii::$app->user->identity ); 

      if( Yii::$app->user->isGuest ){
        echo '<h3> Добро пожаловать, гость! </h3>'; 
      } else {
        echo '<h3> Добро пожаловать, '. Yii::$app->user->identity->username.' ! </h3>'; 
      }
...
⚠️ **GitHub.com Fallback** ⚠️