且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用 Laravel 5.4 和 Passport 进行多重身份验证

更新时间:2023-12-03 22:53:58

如果您仍然需要.

我更喜欢使用角色,有一个很棒的插件:https://github.com/larapacks/授权

I prefer go with roles, there is an amazing plugin for that: https://github.com/larapacks/authorization

但如果您有某种需要,您可以按照以下步骤使用.

But if you somehow needs that, you will be able to use following the steps bellow.

对于多个守卫,您将不得不覆盖一些代码.

For multi guards, you will have to overwrite some code.

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

Instead of loading PassportServiceProvider, you create your own and extends the PassportServiceProvider and overwrites the method makePasswordGrant. On this method, you will change the Passport UserRepository for your own repository extended. On user repository you must to change the static model config for a dynamic one (I load from request attributes, but you can get from anywhere).

您可能需要覆盖其他内容,但我进行了测试并有效.

You may have to overwrite something else, but I made a test and works.

例如:

PassportServiceProvider

PassportServiceProvider

namespace AppProviders;

use LeagueOAuth2ServerAuthorizationServer;
use LeagueOAuth2ServerGrantPasswordGrant;
use LaravelPassportPassportServiceProvider as BasePassportServiceProvider;
use LaravelPassportPassport;

class PassportServiceProvider extends BasePassportServiceProvider
{
    /**
     * Create and configure a Password grant instance.
     *
     * @return PasswordGrant
     */
    protected function makePasswordGrant()
    {
        $grant = new PasswordGrant(
            $this->app->make(AppRepositoriesPassportUserRepository::class),
            $this->app->make(LaravelPassportBridgeRefreshTokenRepository::class)
        );

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

        return $grant;
    }

}

用户存储库

namespace AppRepositories;

use App;
use IlluminateHttpRequest;
use LeagueOAuth2ServerEntitiesClientEntityInterface;
use LaravelPassportBridgeUserRepository;
use LaravelPassportBridgeUser;
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());
    }
}

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

PS: Sorry my bad english.