【问题标题】:What do I do when I want to separate models with authentication plugins?当我想使用身份验证插件分离模型时该怎么办?
【发布时间】:2020-08-06 11:43:14
【问题描述】:

我目前正在 CakePHP4 中实现登录功能。 所以我想把它分为普通用户模型和管理用户模型。

我根本不知道如何做到这一点,我整天都在寻找实现它的方法,但我做不到。

我想在“routes.php”中设置身份验证,但在“Application.php”中“实现 AuthenticationServiceProviderInterface”时遇到问题。我该怎么办?

// routes.php

$routes->scope('/', function (RouteBuilder $builder) {
    /......./

    // ログイン
    //$builder->connect('mgt-account/*', ['controller' => 'MgtAccount', 'action' => 'login', 'prefix' => 'Admin']);
    $builder->connect('users/*', ['controller' => 'Users', 'action' => 'login', 'prefix' => 'Normal']);
  
    /......./
});

$routes->prefix('Normal', function (RouteBuilder $routes) {

    $loginUrl = Router::url('/normal/users/login');
    $fields   = [
        'username' => 'mail',
        'password' => 'password',
    ];
    $service = new AuthenticationService([
        'unauthenticatedRedirect' => $loginUrl,
        'queryParam' => 'redirect',
        ]);
    $service->loadAuthenticator('Authentication.Session');
 
    $service->loadAuthenticator('Authentication.Form', [
        'fields' => $fields,
        'loginUrl' => $loginUrl,
    ]);

    $service->loadIdentifier('Authentication.Password', compact('fields'));

    $routes->registerMiddleware(
        'auth',
        new \Authentication\Middleware\AuthenticationMiddleware($service)
    );
    $routes->applyMiddleware('auth');

    //$routes->connect('/:controller');
    $routes->fallbacks(DashedRoute::class);
});

$routes->prefix('Admin', function (RouteBuilder $routes) {

    $loginUrl = Router::url('/admin/mgt-account/login');
    $fields   = [
        'username' => 'mail',
        'password' => 'password',
    ];
    $service = new AuthenticationService([
        'unauthenticatedRedirect' => $loginUrl,
        'queryParam' => 'redirect',
        ]);
    $service->loadAuthenticator('Authentication.Session');

    $service->loadAuthenticator('Authentication.Form', [
        'fields' => $fields,
        'loginUrl' => $loginUrl,
    ]);

    $service->loadIdentifier('Authentication.Password', compact('fields'));

    $routes->registerMiddleware(
        'auth',
        new \Authentication\Middleware\AuthenticationMiddleware($service)
    );
    $routes->applyMiddleware('auth');

    //$routes->connect('/:controller');
    $routes->fallbacks(DashedRoute::class);
});

<?php
// src/Application.php

declare(strict_types=1);

namespace App;

use Cake\Core\Configure;
use Cake\Core\Exception\MissingPluginException;
use Cake\Error\Middleware\ErrorHandlerMiddleware;
use Cake\Http\BaseApplication;
use Cake\Http\MiddlewareQueue;
use Cake\Routing\Middleware\AssetMiddleware;
use Cake\Routing\Middleware\RoutingMiddleware;

use Authentication\AuthenticationService;
use Authentication\AuthenticationServiceInterface;
use Authentication\AuthenticationServiceProviderInterface;
use Authentication\Middleware\AuthenticationMiddleware;
use Psr\Http\Message\ServerRequestInterface;

/**
 * Application setup class.
 *
 * This defines the bootstrapping logic and middleware layers you
 * want to use in your application.
 */
class Application extends BaseApplication
// I really want to comment out and delete this bottom.
implements AuthenticationServiceProviderInterface
{
    /**
     * Load all the application configuration and bootstrap logic.
     *
     * @return void
     */
    public function bootstrap(): void
    {
        // Call parent to load bootstrap from files.
        parent::bootstrap();

        if (PHP_SAPI === 'cli') {
            $this->bootstrapCli();
        }

        /*
         * Only try to load DebugKit in development mode
         * Debug Kit should not be installed on a production system
         */
        if (Configure::read('debug')) {
            $this->addPlugin('DebugKit');
        }

        // Load more plugins here
    }

    /**
     * Setup the middleware queue your application will use.
     *
     * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to setup.
     * @return \Cake\Http\MiddlewareQueue The updated middleware queue.
     */
    public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
    {
        $middlewareQueue
            // Catch any exceptions in the lower layers,
            // and make an error page/response
            ->add(new ErrorHandlerMiddleware(Configure::read('Error')))

            // Handle plugin/theme assets like CakePHP normally does.
            ->add(new AssetMiddleware([
                'cacheTime' => Configure::read('Asset.cacheTime'),
            ]))

            // Add routing middleware.
            // If you have a large number of routes connected, turning on routes
            // caching in production could improve performance. For that when
            // creating the middleware instance specify the cache config name by
            // using it's second constructor argument:
            // `new RoutingMiddleware($this, '_cake_routes_')`
            ->add(new RoutingMiddleware($this))

            // I really want to comment out and delete this bottom.
            ->add(new AuthenticationMiddleware($this));

        return $middlewareQueue;
    }

    /**
     * Bootrapping for CLI application.
     *
     * That is when running commands.
     *
     * @return void
     */
    protected function bootstrapCli(): void
    {
        try {
            $this->addPlugin('Bake');
        } catch (MissingPluginException $e) {
            // Do not halt if the plugin is missing
        }

        $this->addPlugin('Migrations');

        // Load more plugins here
    }

    // I really want to comment out and delete this bottom.
    public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
    {
        $authenticationService = new AuthenticationService([
            'unauthenticatedRedirect' => '/normal/users/login',
            'queryParam' => 'redirect',
        ]);

 
        $authenticationService->loadIdentifier('Authentication.Password', [
            'fields' => [
                'username' => 'mail',
                'password' => 'password',
            ]
        ]);


        $authenticationService->loadAuthenticator('Authentication.Session');

        $authenticationService->loadAuthenticator('Authentication.Form', [
            'fields' => [
                'username' => 'mail',
                'password' => 'password',
            ],
            'loginUrl' => '/normal/users/login',
        ]);

        return $authenticationService;
    }
}

由于这是我第一次使用“stackoverflow”,我不知道如何提出一个好的问题。如果您能帮助我,我将不胜感激。

如果你能指出来,我将不胜感激。

谢谢。

【问题讨论】:

  • 这通常不是通过两个单独的登录来完成的,而是通过将角色附加到用户并仅允许根据用户的角色访问某些内容。
  • 感谢您与我联系。抱歉,CakePHP 是我的第一本书,我想知道你能否告诉我更多关于它的信息。
  • 我是否向您推荐了此网页,或者我是否有所作为? link 这是否意味着应该有一张桌子?如果我真的想使用两个表怎么办?
  • 我认为该页面是关于其他内容的。不运行两个单独的身份验证,而是在站点的子文件夹中运行标准的 CakePHP 应用程序。
  • 如果你真的要使用两张表,我对你没有任何帮助。我可以告诉你,与基于角色的方法相比,它可能会使事情变得相当复杂。为你正在做的事情寻求帮助会更难,因为这并不常见。由于这一切,您的代码最终可能会变得更加脆弱。如果您需要更改有关身份验证的内容,可能需要在两个地方进行所有这些更改。当然,如果你愿意,你可以继续走这条路。问问自己,您是否真的需要这样做,或者您是否正在尝试使圆钉适合方孔。

标签: cakephp cakephp-4.x


【解决方案1】:

我相信答案是根据当前请求(管理员或普通用户)加载正确的中间件身份验证器。但我还没有多重身份验证,所以可能不正确。在您调用 loadIdentifier() 的 Application.php 方法 getAuthenticationService() 中,根据当前请求 URL(或者您区分管理 url)指定一个“解析器”或另一个。

CakePHP 4.x 文档中有一节介绍了多种身份验证方案。我相信你可以使用两个不同的表。 Configuring Multiple Authentication Setups

这个论坛项目可能有你需要的答案(问题下方的答案):Multiple Authentication Setups

【讨论】:

  • 抱歉耽搁了谢谢。我根据 Edward Barnard 昨天给我的链接实现了它,并且我成功地将身份验证插件与两个单独的表一起使用。谢谢爱德华·巴纳德,我真的很感激。从心底里感谢你。我是日本人,还没有掌握我的英语技能,所以我为我的措辞模糊道歉。很有帮助!
  • @IjIj 欢迎来到 Stack Overflow。我很高兴这对你有用。我将在我自己的项目中做类似的事情。
猜你喜欢
  • 2012-05-19
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-03
相关资源
最近更新 更多