yiisoft/user 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

yiisoft/user

Composer 安装命令:

composer require yiisoft/user

包简介

Convenient user identity management and access checking

关键字:

README 文档

README

Yii

Yii User


Latest Stable Version Total Downloads Build status Code Coverage Mutation testing badge static analysis type-coverage

The package handles user-related functionality:

  • Login and logout.
  • Getting currently logged in identity.
  • Changing current identity.
  • Access checking for current user.
  • Auto login based on identity from request attribute.
  • Auto login or "remember me" based on request cookie.

Requirements

  • PHP 8.1 - 8.5.

Installation

The package could be installed with Composer:

composer require yiisoft/user

General usage

This package is an addition to yiisoft/auth and provides additional functionality for interacting with user identity.

Working with identity

The CurrentUser class is responsible for login and logout, as well as for providing data about the current user identity.

/** 
 * @var \Psr\EventDispatcher\EventDispatcherInterface $eventDispatcher
 * @var \Yiisoft\Auth\IdentityRepositoryInterface $identityRepository
 */

$currentUser = new \Yiisoft\User\CurrentUser($identityRepository, $eventDispatcher);

If the user has not been logged in, then the current user is a guest:

$currentUser->getIdentity(); // \Yiisoft\User\Guest\GuestIdentity instance
$currentUser->getId(); // null
$currentUser->isGuest(); // bool

If you need to use a custom identity class to represent guest user, you should pass an instance of GuestIdentityFactoryInterface as a third optional parameter when creating CurrentUser:

/** 
 * @var \Psr\EventDispatcher\EventDispatcherInterface $eventDispatcher
 * @var \Yiisoft\Auth\IdentityRepositoryInterface $identityRepository
 * @var \Yiisoft\User\Guest\GuestIdentityFactoryInterface $guestIdentityFactory
 */

$currentUser = new \Yiisoft\User\CurrentUser($identityRepository, $eventDispatcher, $guestIdentityFactory);

Also, you can override an identity instance in runtime:

/** 
 * @var \Yiisoft\Auth\IdentityInterface $identity
 */

$currentUser->getIdentity(); // Original identity instance
$currentUser->overrideIdentity($identity);
$currentUser->getIdentity(); // Override identity instance
$currentUser->clearIdentityOverride();
$currentUser->getIdentity(); // Original identity instance

It can be useful to allow admin or developer to validate another user's problems.

Login and logout

There are two methods for login and logout:

/**
 * @var \Yiisoft\Auth\IdentityInterface $identity
 */

$currentUser->getIdentity(); // GuestIdentityInterface instance

if ($currentUser->login($identity)) {
    $currentUser->getIdentity(); // $identity
    // Some actions
}

if ($currentUser->logout()) {
    $currentUser->getIdentity(); // GuestIdentityInterface instance
    // Some actions
}

Both methods trigger events. Events are of the following classes:

  • Yiisoft\User\Event\BeforeLogin - triggered at the beginning of login process. Listeners of this event may call $event->invalidate() to cancel the login process.
  • Yiisoft\User\Event\AfterLogin - triggered at the ending of login process.
  • Yiisoft\User\Event\BeforeLogout - triggered at the beginning of logout process. Listeners of this event may call $event->invalidate() to cancel the logout process.
  • Yiisoft\User\Event\AfterLogout - triggered at the ending of logout process.

Listeners of these events can get an identity instance participating in the process using $event->getIdentity(). Events are dispatched by Psr\EventDispatcher\EventDispatcherInterface instance, which is specified in the constructor when the Yiisoft\User\CurrentUser instance is initialized.

Checking user access

To be able to check whether the current user can perform an operation corresponding to a given permission, you need to set an access checker (see yiisoft/access) instance:

/** 
 * @var \Yiisoft\Access\AccessCheckerInterface $accessChecker
 */
 
$currentUser = $currentUser->withAccessChecker($accessChecker);

To perform the check, use can() method:

// The name of the permission (e.g. "edit post") that needs access check.
$permissionName = 'edit-post'; // Required.

// Name-value pairs that would be passed to the rules associated with the roles and permissions assigned to the user.
$params = ['postId' => 42]; // Optional. Default is empty array.

if ($currentUser->can($permissionName, $params)) {
    // Some actions
}

Note that in case access checker is not provided via withAccessChecker() method, can() will always return false.

Session usage

The current user can store user ID and authentication timeouts for auto-login in the session. To do this, you need to provide a session (see yiisoft/session) instance:

/** 
 * @var \Yiisoft\Session\SessionInterface $session
 */
 
$currentUser = $currentUser->withSession($session);

You can set timeout (number of seconds), during which the user will be logged out automatically in case of remaining inactive:

$currentUser = $currentUser->withAuthTimeout(3600);

Also, an absolute timeout (number of seconds) could be used. The user will be logged out automatically regardless of activity:

$currentUser = $currentUser->withAbsoluteAuthTimeout(3600);

By default, timeouts are not used, so the user will be logged out after the current session expires.

Using with event loop

The Yiisoft\User\CurrentUser instance is stateful, so when you build long-running applications with tools like Swoole or RoadRunner you should reset the state at every request. For this purpose, you can use the clear() method.

Authentication methods

This package provides two authentication methods, WebAuth and ApiAuth, that implement the Yiisoft\Auth\AuthenticationMethodInterface. Both can be provided to the Yiisoft\Auth\Authentication middleware as authentication method.

WebAuth

WebAuth is used to authenticate users in the classic web applications. If authentication is failed, it creates a new instance of the response and adds a Location header with a temporary redirect to the authentication URL, by default /login.

You can change authentication URL by calling WebAuth::withAuthUrl() method:

use Yiisoft\User\Method\WebAuth;

$authenticationMethod = new WebAuth();

// Returns a new instance with the specified authentication URL.
$authenticationMethod = $authenticationMethod->withAuthUrl('/auth');

or in the DI container:

// config/web/di/auth.php
return [
    WebAuth::class => [
        'withAuthUrl()' => ['/auth'],
    ],
];

or through the parameter authUrl of the yiisoft/user config group, yiisoft/config package must be installed:

// config/web/params.php
return [
    'yiisoft/user' => [
        'authUrl' => '/auth',
    ],
];

If the application is used along with the yiisoft/config, the package is configured automatically to use WebAuth as default implementation of Yiisoft\Auth\AuthenticationMethodInterface.

ApiAuth

ApiAuth is used to authenticate users in the API clients. If authentication is failed, it returns the response from the Yiisoft\Auth\Middleware\Authentication::authenticationFailureHandler handler.

To use ApiAuth as an authentication method, you need or provide the ApiAuth instance to the Yiisoft\Auth\Middleware\Authentication middleware:

use Yiisoft\Auth\Middleware\Authentication;
use Yiisoft\User\Method\ApiAuth;

$authenticationMethod = new ApiAuth();

$middleware = new Authentication(
    $authenticationMethod,
    $responseFactory // PSR-17 ResponseFactoryInterface
);

of to define it as an implementation of Yiisoft\Auth\AuthenticationMethodInterface in the DI container configuration:

// config/web/di/auth.php
use Yiisoft\Auth\AuthenticationMethodInterface;
use Yiisoft\User\Method\ApiAuth;

return [
    AuthenticationMethodInterface::class => ApiAuth::class,
];

For more information about the authentication middleware and authentication methods, see the yiisoft/auth.

Auto login through identity from request attribute

For auto login, you can use the Yiisoft\User\Login\LoginMiddleware. This middleware automatically logs user in if Yiisoft\Auth\IdentityInterface instance presents in a request attribute. It is usually put there by Yiisoft\Auth\Middleware\Authentication.

Please note that Yiisoft\Auth\Middleware\Authentication should be located before Yiisoft\User\Login\LoginMiddleware in the middleware stack.

Auto login through cookie

In order to log user in automatically based on request cookie presence, use Yiisoft\User\Login\Cookie\CookieLoginMiddleware.

To use a middleware, you need to implement Yiisoft\User\Login\Cookie\CookieLoginIdentityInterface and also implement and use an instance of IdentityRepositoryInterface in the CurrentUser, which will return CookieLoginIdentityInterface:

use App\CookieLoginIdentity;
use Yiisoft\Auth\IdentityRepositoryInterface;

final class CookieLoginIdentityRepository implements IdentityRepositoryInterface
{
    private Storage $storage;

    public function __construct(Storage $storage)
    {
        $this->storage = $storage;
    }

    public function findIdentity(string $id): ?Identity
    {   
        return new CookieLoginIdentity($this->storage->findOne($id));
    }
}

The CookieLoginMiddleware will check for the existence of a cookie in the request, validate it and login the user automatically.

Creating a cookie

By default, you should set cookie for auto login manually in your application after logging user in:

public function login(
    \Psr\Http\Message\ServerRequestInterface $request,
    \Psr\Http\Message\ResponseFactoryInterface $responseFactory,
    \Yiisoft\User\Login\Cookie\CookieLogin $cookieLogin,
    \Yiisoft\User\CurrentUser $currentUser
): \Psr\Http\Message\ResponseInterface {
    $response = $responseFactory->createResponse();
    $body = $request->getParsedBody();
    
    // Get user identity based on body content.
    
    /** @var \Yiisoft\User\Login\Cookie\CookieLoginIdentityInterface $identity */
    
    if ($currentUser->login($identity) && ($body['rememberMe'] ?? false)) {
        $response = $cookieLogin->addCookie($identity, $response);
    }
    
    return $response;
}

In the above rememberMe in the request body may come from a "remember me" checkbox in the form. End user decides if he wants to be logged in automatically. If you do not need the user to be able to choose and want to always use "remember me", you can enable it via the forceAddCookie in params.php:

return [
    'yiisoft/user' => [
        'authUrl' => '/login',
        'cookieLogin' => [
            'forceAddCookie' => true,
            'duration' => 'P5D', // 5 days
        ],
    ],
];

If you want the cookie to be a session cookie, change the duration to null.

Removing a cookie

The Yiisoft\User\Login\Cookie\CookieLoginMiddleware automatically removes the cookie after the logout. But you can also remove the cookie manually:

public function logout(
    \Psr\Http\Message\ResponseFactoryInterface $responseFactory,
    \Yiisoft\User\Login\Cookie\CookieLogin $cookieLogin,
    \Yiisoft\User\CurrentUser $currentUser
): \Psr\Http\Message\ResponseInterface {
    $response = $responseFactory
        ->createResponse(302)
        ->withHeader('Location', '/');
    
    // Regenerate cookie login key to `Yiisoft\User\Login\Cookie\CookieLoginIdentityInterface` instance.
    
    if ($currentUser->logout()) {
        $response = $cookieLogin->expireCookie($response);
    }
    
    return $response;
}

Preventing the substitution of cookies

The login cookie value is stored raw. To prevent the substitution of the cookie value, you can use a Yiisoft\Cookies\CookieMiddleware. For more information, see Yii guide to cookies.

Please note that Yiisoft\Cookies\CookieMiddleware should be located before Yiisoft\User\Login\Cookie\CookieLoginMiddleware in the middleware stack.

You can find examples of the above features in the yiisoft/demo.

Documentation

If you need help or have a question, the Yii Forum is a good place for that. You may also check out other Yii Community Resources.

License

The Yii User is free software. It is released under the terms of the BSD License. Please see LICENSE for more information.

Maintained by Yii Software.

Support the project

Open Collective

Follow updates

Official website Twitter Telegram Facebook Slack

yiisoft/user 适用场景与选型建议

yiisoft/user 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 138.89k 次下载、GitHub Stars 达 19, 最近一次更新时间为 2020 年 11 月 05 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「user」 「yiisoft」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 yiisoft/user 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 yiisoft/user 我们能提供哪些服务?
定制开发 / 二次开发

基于 yiisoft/user 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 138.89k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 19
  • 点击次数: 27
  • 依赖项目数: 22
  • 推荐数: 2

GitHub 信息

  • Stars: 19
  • Watchers: 12
  • Forks: 6
  • 开发语言: PHP

其他信息

  • 授权协议: BSD-3-Clause
  • 更新时间: 2020-11-05