master

laravel/framework

Last updated at: 29/12/2023 09:20

AuthManager.php

TLDR

The AuthManager.php file in the Illuminate\Auth namespace defines the AuthManager class, which is responsible for managing the creation and resolution of authentication guards in Laravel. It provides methods for creating session-based and token-based guards, resolving guards from the local cache, setting the default guard driver, and registering custom driver creators. It also allows for resolving users using a callback, extending guard functionality, and registering custom provider creators.

Methods

guard

This method is used to retrieve an authentication guard from the local cache. It takes an optional $name parameter which specifies the name of the guard to retrieve. If no name is provided, it returns the default guard driver. If the guard has not been resolved before, it resolves it using the resolve method. It returns an instance of \Illuminate\Contracts\Auth\Guard or \Illuminate\Contracts\Auth\StatefulGuard.

createSessionDriver

This method is used to create a session-based authentication guard. It takes the guard $name and $config as parameters. It creates an instance of \Illuminate\Auth\SessionGuard and sets the necessary dependencies such as the user provider, session store, cookie jar, dispatcher, and request. It returns the created guard instance.

createTokenDriver

This method is used to create a token-based authentication guard. It takes the guard $name and $config as parameters. It creates an instance of \Illuminate\Auth\TokenGuard and sets the necessary dependencies such as the user provider and request. It returns the created guard instance.

getDefaultDriver

This method is used to get the default authentication driver name. It retrieves the value from the application configuration using the key auth.defaults.guard and returns it.

shouldUse

This method is used to set the default guard driver that the factory should serve. It takes the $name parameter, which specifies the name of the guard to set as default. If no name is provided, it uses the default guard driver from the configuration. It sets the default driver in the application configuration and updates the user resolver callback.

setDefaultDriver

This method is used to set the default authentication driver name. It takes the guard $name as a parameter and updates the auth.defaults.guard configuration value with the provided name.

viaRequest

This method is used to register a new callback based request guard. It takes the $driver and $callback as parameters. It creates an instance of \Illuminate\Auth\RequestGuard and sets the necessary dependencies such as the request and user provider. It returns the current instance of the AuthManager.

userResolver

This method is used to get the user resolver callback. It returns the user resolver callback stored in the AuthManager.

resolveUsersUsing

This method is used to set the callback to be used to resolve users. It takes the $userResolver parameter, which is a closure that accepts the user identifier and returns a user instance. It updates the user resolver callback in the AuthManager and returns the current instance.

extend

This method is used to register a custom driver creator closure. It takes the $driver and $callback as parameters. It registers the callback as a custom creator for the specified driver in the AuthManager and returns the current instance.

provider

This method is used to register a custom provider creator closure. It takes the $name and $callback as parameters. It registers the callback as a custom creator for the specified provider name in the AuthManager and returns the current instance.

hasResolvedGuards

This method is used to determine if any guards have already been resolved. It checks if the number of resolved guards in the guards property is greater than zero and returns a boolean value.

forgetGuards

This method is used to forget all of the resolved guard instances. It clears the guards property in the AuthManager and returns the current instance.

setApplication

This method is used to set the application instance used by the manager. It takes the $app parameter, which is an instance of \Illuminate\Contracts\Foundation\Application, and sets it in the AuthManager. It returns the current instance.

__call

This magic method is used to dynamically call the default driver instance. It takes the $method name and $parameters as parameters. It calls the specified method on the default guard instance and passes the parameters. It returns the result of the method call.

Classes

None

<?php

namespace Illuminate\Auth;

use Closure;
use Illuminate\Contracts\Auth\Factory as FactoryContract;
use InvalidArgumentException;

/**
 * @mixin \Illuminate\Contracts\Auth\Guard
 * @mixin \Illuminate\Contracts\Auth\StatefulGuard
 */
class AuthManager implements FactoryContract
{
    use CreatesUserProviders;

    /**
     * The application instance.
     *
     * @var \Illuminate\Contracts\Foundation\Application
     */
    protected $app;

    /**
     * The registered custom driver creators.
     *
     * @var array
     */
    protected $customCreators = [];

    /**
     * The array of created "drivers".
     *
     * @var array
     */
    protected $guards = [];

    /**
     * The user resolver shared by various services.
     *
     * Determines the default user for Gate, Request, and the Authenticatable contract.
     *
     * @var \Closure
     */
    protected $userResolver;

    /**
     * Create a new Auth manager instance.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function __construct($app)
    {
        $this->app = $app;

        $this->userResolver = fn ($guard = null) => $this->guard($guard)->user();
    }

    /**
     * Attempt to get the guard from the local cache.
     *
     * @param  string|null  $name
     * @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
     */
    public function guard($name = null)
    {
        $name = $name ?: $this->getDefaultDriver();

        return $this->guards[$name] ?? $this->guards[$name] = $this->resolve($name);
    }

    /**
     * Resolve the given guard.
     *
     * @param  string  $name
     * @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
     *
     * @throws \InvalidArgumentException
     */
    protected function resolve($name)
    {
        $config = $this->getConfig($name);

        if (is_null($config)) {
            throw new InvalidArgumentException("Auth guard [{$name}] is not defined.");
        }

        if (isset($this->customCreators[$config['driver']])) {
            return $this->callCustomCreator($name, $config);
        }

        $driverMethod = 'create'.ucfirst($config['driver']).'Driver';

        if (method_exists($this, $driverMethod)) {
            return $this->{$driverMethod}($name, $config);
        }

        throw new InvalidArgumentException(
            "Auth driver [{$config['driver']}] for guard [{$name}] is not defined."
        );
    }

    /**
     * Call a custom driver creator.
     *
     * @param  string  $name
     * @param  array  $config
     * @return mixed
     */
    protected function callCustomCreator($name, array $config)
    {
        return $this->customCreators[$config['driver']]($this->app, $name, $config);
    }

    /**
     * Create a session based authentication guard.
     *
     * @param  string  $name
     * @param  array  $config
     * @return \Illuminate\Auth\SessionGuard
     */
    public function createSessionDriver($name, $config)
    {
        $provider = $this->createUserProvider($config['provider'] ?? null);

        $guard = new SessionGuard(
            $name,
            $provider,
            $this->app['session.store'],
            rehashOnLogin: $this->app['config']->get('hashing.rehash_on_login', true),
        );

        // When using the remember me functionality of the authentication services we
        // will need to be set the encryption instance of the guard, which allows
        // secure, encrypted cookie values to get generated for those cookies.
        if (method_exists($guard, 'setCookieJar')) {
            $guard->setCookieJar($this->app['cookie']);
        }

        if (method_exists($guard, 'setDispatcher')) {
            $guard->setDispatcher($this->app['events']);
        }

        if (method_exists($guard, 'setRequest')) {
            $guard->setRequest($this->app->refresh('request', $guard, 'setRequest'));
        }

        if (isset($config['remember'])) {
            $guard->setRememberDuration($config['remember']);
        }

        return $guard;
    }

    /**
     * Create a token based authentication guard.
     *
     * @param  string  $name
     * @param  array  $config
     * @return \Illuminate\Auth\TokenGuard
     */
    public function createTokenDriver($name, $config)
    {
        // The token guard implements a basic API token based guard implementation
        // that takes an API token field from the request and matches it to the
        // user in the database or another persistence layer where users are.
        $guard = new TokenGuard(
            $this->createUserProvider($config['provider'] ?? null),
            $this->app['request'],
            $config['input_key'] ?? 'api_token',
            $config['storage_key'] ?? 'api_token',
            $config['hash'] ?? false
        );

        $this->app->refresh('request', $guard, 'setRequest');

        return $guard;
    }

    /**
     * Get the guard configuration.
     *
     * @param  string  $name
     * @return array
     */
    protected function getConfig($name)
    {
        return $this->app['config']["auth.guards.{$name}"];
    }

    /**
     * Get the default authentication driver name.
     *
     * @return string
     */
    public function getDefaultDriver()
    {
        return $this->app['config']['auth.defaults.guard'];
    }

    /**
     * Set the default guard driver the factory should serve.
     *
     * @param  string  $name
     * @return void
     */
    public function shouldUse($name)
    {
        $name = $name ?: $this->getDefaultDriver();

        $this->setDefaultDriver($name);

        $this->userResolver = fn ($name = null) => $this->guard($name)->user();
    }

    /**
     * Set the default authentication driver name.
     *
     * @param  string  $name
     * @return void
     */
    public function setDefaultDriver($name)
    {
        $this->app['config']['auth.defaults.guard'] = $name;
    }

    /**
     * Register a new callback based request guard.
     *
     * @param  string  $driver
     * @param  callable  $callback
     * @return $this
     */
    public function viaRequest($driver, callable $callback)
    {
        return $this->extend($driver, function () use ($callback) {
            $guard = new RequestGuard($callback, $this->app['request'], $this->createUserProvider());

            $this->app->refresh('request', $guard, 'setRequest');

            return $guard;
        });
    }

    /**
     * Get the user resolver callback.
     *
     * @return \Closure
     */
    public function userResolver()
    {
        return $this->userResolver;
    }

    /**
     * Set the callback to be used to resolve users.
     *
     * @param  \Closure  $userResolver
     * @return $this
     */
    public function resolveUsersUsing(Closure $userResolver)
    {
        $this->userResolver = $userResolver;

        return $this;
    }

    /**
     * Register a custom driver creator Closure.
     *
     * @param  string  $driver
     * @param  \Closure  $callback
     * @return $this
     */
    public function extend($driver, Closure $callback)
    {
        $this->customCreators[$driver] = $callback;

        return $this;
    }

    /**
     * Register a custom provider creator Closure.
     *
     * @param  string  $name
     * @param  \Closure  $callback
     * @return $this
     */
    public function provider($name, Closure $callback)
    {
        $this->customProviderCreators[$name] = $callback;

        return $this;
    }

    /**
     * Determines if any guards have already been resolved.
     *
     * @return bool
     */
    public function hasResolvedGuards()
    {
        return count($this->guards) > 0;
    }

    /**
     * Forget all of the resolved guard instances.
     *
     * @return $this
     */
    public function forgetGuards()
    {
        $this->guards = [];

        return $this;
    }

    /**
     * Set the application instance used by the manager.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return $this
     */
    public function setApplication($app)
    {
        $this->app = $app;

        return $this;
    }

    /**
     * Dynamically call the default driver instance.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        return $this->guard()->{$method}(...$parameters);
    }
}