yii1tech/web-user

为 Yii1 提供高级的 Web 用户组件

1.0.0 2023-06-16 12:13 UTC

This package is auto-updated.

Last update: 2024-09-16 14:46:13 UTC


README

为 Yii 1 提供高级的 Web 用户组件


本扩展为 Yii 1 提供高级的 Web 用户组件。

有关许可信息,请参阅 LICENSE 文件。

Latest Stable Version Total Downloads Build Status

安装

安装此扩展的首选方法是通过 composer

运行

php composer.phar require --prefer-dist yii1tech/web-user

或添加

"yii1tech/web-user": "*"

到您的 composer.json 文件的 "require" 部分。

用法

此扩展提供了 Yii 1 标准组件 CWebUser 的高级版本。类 yii1tech\web\user\WebUser 增加了为认证流程事件设置外部处理器的功能。以下事件可用

  • 'onAfterRestore' - 在从会话、cookie 等恢复用户数据后触发。
  • 'onBeforeLogin' - 在用户登录之前触发。
  • 'onAfterLogin' - 在用户成功登录后触发。
  • 'onBeforeLogout' - 在用户登出之前触发。
  • 'onAfterLogout' - 在用户成功登出后触发。

应用程序配置示例

<?php

return [
    'components' => [
        'user' => [
            'class' => yii1tech\web\user\WebUser::class,
            'onAfterLogin' => function (CEvent $event) {
                Yii::log('Login User ID=' . $event->sender->getId());
            },
        ],
        // ...
    ],
    // ...
];

所有引入的事件中最值得注意的是 'onAfterRestore'。默认情况下,Yii 不会在每个后续请求上重新检查用户的身份可用性。一旦用户登录,他保持认证状态,即使相关记录在 "users" 表中被删除。您可以使用 'onAfterRestore' 事件来确保被删除或禁止的用户会立即失去对您的应用程序的访问权限。例如

<?php

return [
    'components' => [
        'user' => [
            'class' => yii1tech\web\user\WebUser::class,
            'onAfterRestore' => function (CEvent $event) {
                $user = User::model()->findByPk($event->sender->getId());
                
                if (empty($user) || $user->is_banned) {
                    $event->sender->logout(false);
                }
            },
        ],
        // ...
    ],
    // ...
];

通过 WebUser 操作 ActiveRecord 模型

此包还为 yii1tech\web\user\WebUser 提供了 yii1tech\web\user\ActiveRecordModelBehavior 行为,允许在 WebUser 组件级别操作 ActiveRecord 模型。

应用程序配置示例

<?php

return [
    'components' => [
        'user' => [
            'class' => yii1tech\web\user\WebUser::class,
            'behaviors' => [
                'modelBehavior' => [
                    'class' => yii1tech\web\user\ActiveRecordModelBehavior::class,
                    'modelClass' => app\models\User::class, // ActiveRecord class to used for model source
                    'attributeToStateMap' => [ // map for WebUser states fill up from ActiveRecord model attributes
                        'username' => '__name', // matches `Yii::app()->user->getName()`
                        'email' => 'email', // matches `Yii::app()->user->getState('email')`
                    ],
                ],
            ],
        ],
        // ...
    ],
    // ...
];

在您的程序中,您始终可以通过 "user" 应用程序组件访问当前认证用户的模型。例如

<?php

$user = Yii::app()->user->getModel();

var_dump($user->id == Yii::app()->user->getId()); // outputs `true`
var_dump($user->username == Yii::app()->user->getName()); // outputs `true`
var_dump($user->email == Yii::app()->user->getState('email')); // outputs `true`

$user->setAttributes($_POST['User']);
$user->save();

如果没有认证用户,yii1tech\web\user\ActiveRecordModelBehavior::getModel() 返回 null。例如

<?php

$user = Yii::app()->user->getModel();
if ($user) {
    var_dump(Yii::app()->user->getIsGuest()); // outputs `false`
} else {
    var_dump(Yii::app()->user->getIsGuest()); // outputs `true`
}

默认情况下,yii1tech\web\user\ActiveRecordModelBehavior 会自动注销无法从数据库获取其相关记录的任何认证用户。您可以通过 yii1tech\web\user\ActiveRecordModelBehavior::$autoSyncModel 控制此行为。

您可以通过 yii1tech\web\user\ActiveRecordModelBehavior::$modelFindCriteria 为用户搜索查询添加额外的条件。这允许您处理用户封禁或账户确认等问题。例如

<?php

return [
    'components' => [
        'user' => [
            'class' => yii1tech\web\user\WebUser::class,
            'behaviors' => [
                'modelBehavior' => [
                    'class' => yii1tech\web\user\ActiveRecordModelBehavior::class,
                    'modelClass' => app\models\User::class,
                    'modelFindCriteria' => [
                        'scopes' => [
                            'activeOnly',
                        ],
                        'condition' => 'is_banned = 0',
                    ],
                ],
            ],
        ],
        // ...
    ],
    // ...
];

您可以使用 yii1tech\web\user\ActiveRecordModelBehavior::setModel() 方法切换用户身份。例如

<?php

$user = User::model()->findByPk(1);

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

var_dump(Yii::app()->user->getIsGuest()); // outputs `false`
var_dump($user->id == Yii::app()->user->getId()); // outputs `true`

注意:虽然可以使用 yii1tech\web\user\ActiveRecordModelBehavior::setModel() 方法切换用户身份,但它不等于 \CWebUser::login()\CWebUser::changeIdentity(),因为它不处理相关的 Cookies 和一些其他相关功能。

您可以将 yii1tech\web\user\ActiveRecordModelBehavior::setModel()"yii1tech/session-dummy" 结合使用,以轻松创建 API 的认证流程。例如

<?php

namespace app\web\controllers;

use app\models\OAuthToken;
use app\models\User;
use CController;
use Yii;
use yii1tech\session\dummy\DummySession;

class ApiController extends CController
{
    public function init()
    {
        parent::init();
        
        // mock session, so it does not send any Cookies to the API client:
        Yii::app()->setComponent('session', new DummySession(), false);
        
        // find OAuth token matching request:
        $oauthToken = OAuthToken::model()->findByPk(Yii::app()->request->getParam('oauth_token'));
        if (!$oauthToken) {
            return;
        }
        
        // find User matching OAuth token:
        $user = User::model()->findByPk($oauthToken->user_id);
        if (!$user) {
            return;
        }
        
        // act as found user:
        Yii::app()->user->setModel($user);
    }
    
    public function filters()
    {
        return [
            'accessControl', // now we can freely use standard "access control" filter and other features
        ];
    }
    
    public function accessRules()
    {
        return [
            // ...
        ];
    }
    
    // ...
}