使用Laravel 5.4和Passport进行Multi Auth

Zub*_*ir1 4 php oauth-2.0 laravel laravel-passport

我正在尝试使用Laravel Passport设置多个身份验证,但它似乎不支持它.我使用密码授予发出令牌,要求我传递想要访问令牌的用户的用户名/密码.

我有3个auth警卫/提供者设置,总共4个.用户,供应商,管理员和API

其中2个Auths需要访问护照,因此每个用户都需要能够发放令牌.但是,Passport会自动获取API身份验证提供程序,但我希望根据登录的用户进行更改.如果用户确实是用户提供商,那么它是供应商,然后是供应商提供商.

但Passport目前只支持1种用户类型,因此默认为API提供者.

这有什么更好的吗?或者我应该使用基于角色的身份验证.

小智 5

如果你还需要.

我更喜欢使用角色,有一个惊人的插件:https://github.com/larapacks/authorization

但是如果你以某种方式需要它,你将能够按照下面的步骤使用.

对于多重防护,您将不得不覆盖一些代码.

您不必加载PassportServiceProvider,而是创建自己的PassportServiceProvider并扩展PassportServiceProvider并覆盖方法makePasswordGrant.在此方法上,您将更改自己的存储库扩展的Passport UserRepository.在用户存储库上,您必须更改动态模型的静态模型配置(我从请求属性加载,但您可以从任何地方获取).

你可能不得不覆盖别的东西,但我做了一个测试并且工作.

例如:

PassportServiceProvider

namespace App\Providers;

use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Grant\PasswordGrant;
use Laravel\Passport\PassportServiceProvider as BasePassportServiceProvider;
use Laravel\Passport\Passport;

class PassportServiceProvider extends BasePassportServiceProvider
{
    /**
     * Create and configure a Password grant instance.
     *
     * @return PasswordGrant
     */
    protected function makePasswordGrant()
    {
        $grant = new PasswordGrant(
            $this->app->make(\App\Repositories\PassportUserRepository::class),
            $this->app->make(\Laravel\Passport\Bridge\RefreshTokenRepository::class)
        );

        $grant->setRefreshTokenTTL(Passport::refreshTokensExpireIn());

        return $grant;
    }

}
Run Code Online (Sandbox Code Playgroud)

UserRepository

namespace App\Repositories;

use App;
use Illuminate\Http\Request;
use League\OAuth2\Server\Entities\ClientEntityInterface;
use Laravel\Passport\Bridge\UserRepository;
use Laravel\Passport\Bridge\User;
use RuntimeException;

class PassportUserRepository extends UserRepository
{
    /**
     * {@inheritdoc}
     */
    public function getUserEntityByUserCredentials($username, $password, $grantType, ClientEntityInterface $clientEntity)
    {
        $guard = App::make(Request::class)->attributes->get('guard') ?: 'api';
        $provider = config("auth.guards.{$guard}.provider");


        if (is_null($model = config("auth.providers.{$provider}.model"))) {
            throw new RuntimeException('Unable to determine user model from configuration.');
        }


        if (method_exists($model, 'findForPassport')) {
            $user = (new $model)->findForPassport($username);
        } else {
            $user = (new $model)->where('email', $username)->first();
        }


        if (! $user ) {
            return;
        } elseif (method_exists($user, 'validateForPassportPasswordGrant')) {
            if (! $user->validateForPassportPasswordGrant($password)) {
                return;
            }
        } elseif (! $this->hasher->check($password, $user->password)) {
            return;
        }

        return new User($user->getAuthIdentifier());
    }
}
Run Code Online (Sandbox Code Playgroud)

PS:对不起,我的英文不好.