Авторизация в Laravel 5.3 из нескольких таблиц | Все о WEB программировании Все о WEB программировании

Основы использования

Теперь можно аутентифицировать пользователей! Вам будут нужны два маршрута: один для перенаправления пользователя на провайдер OAuth, и второй для получения обратного вызова от провайдера после аутентификации. Мы обратимся к Socialite через фасадSocialite:

Автоматическое определение метода класса политики

Часто название правила авторизации совпадает с названием метода контроллера. Например, в нашем примере они оба имеют имя “update”. Для таких случаев в Laravel предусмотрено такое поведение – если в authorize() не передается строка названия метода, то берется название метода контроллера, из которого вызывается authorize():

publicfunctionupdate($id){
	$post = Post::findOrFail($id);

	$this->authorize($post);

	
}

Полный цикл в данном случае выглядит так: Laravel смотрит, какой класс политики зарегистрирован для объекта типа $post (это в нашем случае ), далее смотрит название текущего метода метода контроллера, и вызывает метод update класса PostPolicy

Авторизация (laravel 8.x) — laravel framework russian community

Помимо встроенных служб аутентификации, Laravel также предлагает простой способ авторизации действий пользователя с конкретными ресурсами. Например, даже если пользователь аутентифицирован, то он может быть не авторизован для обновления или удаления определенных моделей Eloquent или записей базы данных вашего приложения. Функционал авторизации Laravel обеспечивает простой и организованный способ управления этими проверками авторизации.

Laravel предлагает два основных способа авторизации действий: шлюзы и политики. Думайте о шлюзах и политиках, как о маршрутах и контроллерах. Шлюзы обеспечивают простой подход к авторизации, основанный на замыкании, в то время как политики, также как контроллеры, группируют логику вокруг конкретной модели или ресурса. В этой документации мы сначала рассмотрим шлюзы, а затем политики.

Вам не нужно выбирать между использованием исключительно шлюзов или исключительно политик при создании приложения. Большинство приложений, скорее всего, будут содержать смесь шлюзов и политик, и это нормально! Шлюзы наиболее применимы к действиям, не связанным с какой-либо моделью или ресурсом, например, просмотр панели администратора. Напротив, политики следует использовать, когда вы хотите разрешить действие для конкретной модели или ресурса.

Похожее:  Давай дружить. OpenId Connect и Yarp / Хабр

Шлюзы – отличный способ изучить основы функционала авторизации Laravel; однако при создании надежных приложений Laravel, вам следует рассмотреть возможность использования политик для организации ваших правил авторизации.

Шлюз – это просто замыкание, которое определяет, имеет ли пользователь право выполнять указанное действие. Обычно шлюзы определяются в методе boot класса AppProvidersAuthServiceProvider с использованием фасада Gate. Шлюзы всегда получают экземпляр пользователя в качестве своего первого аргумента и могут получать дополнительные аргументы, например, модель Eloquent.

В этом примере мы определим шлюз, решающий, может ли пользователь обновить указанную модель AppModelsPost. Шлюз выполнит это, сравнив идентификатор пользователя с идентификатором user_id пользователя, создавшего пост:

useAppModelsPost;
useAppModelsUser;
useIlluminateSupportFacadesGate;

publicfunctionboot(){
    $this->registerPolicies();

    Gate::define('update-post', function(User $user, Post $post){
        return $user->id === $post->user_id;
    });
}

Шлюзы также могут быть определены с использованием callback-массива:

useAppPoliciesPostPolicy;
useIlluminateSupportFacadesGate;

publicfunctionboot(){
    $this->registerPolicies();

    Gate::define('update-post', [PostPolicy::class, 'update']);
}

Чтобы авторизовать действие с помощью шлюзов, вы должны использовать методы allows или denies фасада Gate. Обратите внимание, что вам не требуется передавать в эти методы аутентифицированного в данный момент пользователя. Laravel автоматически позаботится о передаче пользователя в замыкание шлюза. Обычно методы авторизации шлюза вызываются в контроллерах вашего приложения перед выполнением действия, требующего авторизации:

<?phpnamespaceAppHttpControllers;

useAppHttpControllersController;
useAppModelsPost;
useIlluminateHttpRequest;
useIlluminateSupportFacadesGate;

classPostControllerextendsController{
    publicfunctionupdate(Request $request, Post $post){
        if (! Gate::allows('update-post', $post)) {
            abort(403);
        }

        
    }
}

Если вы хотите определить, авторизован ли другой (не аутентифицированный в настоящий момент) пользователь для выполнения действия, то вы можете использовать метод forUser фасада Gate:

if (Gate::forUser($user)->allows('update-post', $post)) {
    
}

if (Gate::forUser($user)->denies('update-post', $post)) {
    
}

Вы можете определить авторизацию нескольких действий одновременно, используя методы any или none:

if (Gate::any(['update-post', 'delete-post'], $post)) {
    
}

if (Gate::none(['update-post', 'delete-post'], $post)) {
    
}

Если вы хотите попытаться авторизовать действие и автоматически выбросить исключение IlluminateAuthAccessAuthorizationException при не авторизованном действии пользователя, то вы можете использовать метод authorize фасада Gate. Экземпляры AuthorizationException автоматически преобразуются в 403 HTTP-ответ обработчиком исключений Laravel:

Gate::authorize('update-post', $post);

Методы шлюза для авторизации полномочий (allows, denies, check, any, none, authorize, can, cannot) и директивы авторизации Blade (@can, @cannot, @canany) могут получать массив в качестве второго аргумента. Эти элементы массива передаются в качестве параметров замыканию шлюза и могут использоваться как дополнительный контекст при принятии решений об авторизации:

useAppModelsCategory;
useAppModelsUser;
useIlluminateSupportFacadesGate;

Gate::define('create-post', function(User $user, Category $category, $pinned){
    if (! $user->canPublishToGroup($category->group)) {
        returnfalse;
    } elseif ($pinned && ! $user->canPinPosts()) {
        returnfalse;
    }

    returntrue;
});

if (Gate::check('create-post', [$category, $pinned])) {
    
}

До сих пор мы рассматривали шлюзы, возвращающие простые логические значения. По желанию можно вернуть более подробный ответ, содержащий также сообщение об ошибке. Для этого вы можете вернуть экземпляр IlluminateAuthAccessResponse из вашего шлюза:

useAppModelsUser;
useIlluminateAuthAccessResponse;
useIlluminateSupportFacadesGate;

Gate::define('edit-settings', function(User $user){
    return $user->isAdmin
                ? Response::allow()
                : Response::deny('Вы должны быть администратором.');
});

Даже когда вы возвращаете ответ авторизации из вашего шлюза, метод Gate::allows все равно будет возвращать простое логическое значение; однако вы можете использовать метод Gate::inspect, чтобы получить полный возвращенный шлюзом ответ авторизации:

$response = Gate::inspect('edit-settings');

if ($response->allowed()) {
    
} else {
    echo $response->message();
}

При использовании метода Gate::authorize, генерирующего исключение AuthorizationException для неавторизованного действия, сообщение об ошибке из ответа авторизации будет передано в HTTP-ответ:

Gate::authorize('edit-settings');

Иногда бывает необходимо предоставить все полномочия конкретному пользователю. Вы можете использовать метод before для определения замыкания, которое выполняется перед всеми другими проверками авторизации:

useIlluminateSupportFacadesGate;

Gate::before(function($user, $ability){
    if ($user->isAdministrator()) {
        returntrue;
    }
});

Если замыкание before возвращает результат, отличный от null, то этот результат и будет считаться результатом проверки авторизации.

Вы можете использовать метод after для определения замыкания, которое будет выполнено после всех других проверок авторизации:

Gate::after(function($user, $ability, $result, $arguments){
    if ($user->isAdministrator()) {
        returntrue;
    }
});

Подобно методу before, если замыкание after возвращает результат, отличный от null, то этот результат и будет считаться результатом проверки авторизации.

Иногда вы можете захотеть определить, авторизован ли текущий аутентифицированный пользователь для выполнения данного действия без написания специального шлюза, соответствующего этому действию. Laravel позволяет вам выполнять эти типы «встроенных» проверок авторизации с помощью методов Gate::allowIf и Gate::denyIf:

useIlluminateSupportFacadesAuth;

Gate::allowIf(fn ($user) => $user->isAdministrator());

Gate::denyIf(fn ($user) => $user->banned());

Если действие не авторизовано или ни один пользователь в настоящее время не аутентифицирован, Laravel автоматически выдаст исключение IlluminateAuthAccessAuthorizationException. Экземпляры AuthorizationException автоматически преобразуются в HTTP-ответ 403 обработчиком исключений Laravel:

Политики – это классы, которые организуют логику авторизации для конкретной модели или ресурса. Например, если ваше приложение является блогом, то у вас может быть модель AppModelsPost и соответствующая политика AppPoliciesPostPolicy для авторизации действий пользователя, например, создание или обновление постов.

Чтобы сгенерировать новую политику, используйте команду make:policyArtisan. Эта команда поместит новый класс политики в каталог app/Policies вашего приложения. Если этот каталог еще не существует, то Laravel предварительно создаст его:

php artisan make:policy PostPolicy

Команда make:policy сгенерирует пустой класс политики. Если вы хотите создать класс с заготовками методов политики, связанных с просмотром, созданием, обновлением и удалением ресурса, то вы можете указать параметр --model при выполнении команды:

php artisan make:policy PostPolicy --model=Post

После создания класса политики его необходимо зарегистрировать. Регистрация политик – это указание Laravel, какую политику использовать при авторизации действий для конкретного типа модели.

Поставщик AppProvidersAuthServiceProvider вашего приложения содержит свойство $policies, которое сопоставляет ваши модели Eloquent с соответствующими политиками. Регистрация политики проинструктирует Laravel, какую политику использовать при авторизации действий для конкретной модели Eloquent:

<?phpnamespaceAppProviders;

useAppModelsPost;
useAppPoliciesPostPolicy;
useIlluminateFoundationSupportProvidersAuthServiceProviderasServiceProvider;
useIlluminateSupportFacadesGate;

classAuthServiceProviderextendsServiceProvider{
    protected $policies = [
        Post::class => PostPolicy::class,
    ];

    publicfunctionboot(){
        $this->registerPolicies();

        
    }
}

Вместо того чтобы вручную регистрировать политики модели, Laravel может автоматически обнаруживать политики, если модель и политика соответствуют стандартным соглашениям об именах Laravel. Так, например, модели могут быть помещены в каталог app/Models, а политики – в каталог app/Policies. Кроме того, имя политики должно совпадать с названием модели и иметь суффикс Policy. Например, модель User будет сопоставлена классу политики UserPolicy.

Если вы хотите определить свою собственную логику обнаружения политики, то вы можете зарегистрировать замыкание обнаружения политики, используя метод Gate::guessPolicyNamesUsing. Как правило, этот метод следует вызывать из метода boot поставщика AuthServiceProvider вашего приложения:

useIlluminateSupportFacadesGate;

Gate::guessPolicyNamesUsing(function($modelClass){
    
});

Любые политики, которые явно отображены в вашем AuthServiceProvider, будут иметь приоритет над любыми потенциально автоматически обнаруженными политиками.

После регистрации класса политики вы можете добавить методы для каждого из авторизуемых действий. Например, давайте определим метод update в нашем классе PostPolicy, который решает, может ли пользователь обновить указанный экземпляр поста.

Метод update получит в качестве аргументов экземпляры User и Post и должен вернуть true или false, которые будут указывать, авторизован ли пользователь обновлять указанный пост. Итак, в этом примере мы проверим, что идентификатор пользователя совпадает с user_id поста:

<?phpnamespaceAppPolicies;

useAppModelsPost;
useAppModelsUser;

classPostPolicy{
    publicfunctionupdate(User $user, Post $post){
        return $user->id === $post->user_id;
    }
}

Вы можете продолжить определение в политике необходимых методов дополнительных авторизуемых действий. Например, вы можете определить методы view или delete для авторизации различных действий, связанных с Post. Помните, что вы можете дать своим методам политики любые желаемые имена.

Если вы использовали опцию --model при создании своей политики через Artisan, то она уже будет содержать методы для следующих действий: viewAny, view, create, update, delete, restore, и forceDelete.

Все политики извлекаются через контейнер служб Laravel, что позволяет вам объявлять любые необходимые зависимости в конструкторе политики для их автоматического внедрения.

До сих пор мы рассматривали методы политики, возвращающие простые логические значения. По желанию можно вернуть более подробный ответ, содержащий также сообщение об ошибке. Для этого вы можете вернуть экземпляр IlluminateAuthAccessResponse из вашего метода политики:

useAppModelsPost;
useAppModelsUser;
useIlluminateAuthAccessResponse;

publicfunctionupdate(User $user, Post $post){
    return $user->id === $post->user_id
                ? Response::allow()
                : Response::deny('You do not own this post.');
}

При возврате ответа авторизации из вашей политики метод Gate::allows все равно будет возвращать простое логическое значение; однако вы можете использовать метод Gate::inspect, чтобы получить полный возвращенный шлюзом ответ авторизации:

useIlluminateSupportFacadesGate;

$response = Gate::inspect('update', $post);

if ($response->allowed()) {
    
} else {
    echo $response->message();
}

При использовании метода Gate::authorize, генерирующего исключение AuthorizationException для неавторизованного действия, сообщение об ошибке из ответа авторизации будет передано в HTTP-ответ:

Gate::authorize('update', $post);

Некоторые методы политики получают только экземпляр аутентифицированного в данный момент пользователя. Эта ситуация наиболее распространена при авторизации действий create. Например, если вы создаете блог, то вы можете определить, имеет ли пользователь право вообще создавать какие-либо посты. В этих ситуациях ваш метод политики должен рассчитывать только на получение экземпляра пользователя:

publicfunctioncreate(User $user){
    return $user->role == 'writer';
}

По умолчанию все шлюзы и политики автоматически возвращают false, если входящий HTTP-запрос был инициирован не аутентифицированным пользователем. Однако вы можете разрешить прохождение этих проверок авторизации к вашим шлюзам и политикам, пометив в аргументе метода объявленный тип User как обнуляемый, путём добавления префикса в виде знака вопроса (?). Это означает, что значение может быть как объявленного типа User, так и быть равным null:

<?phpnamespaceAppPolicies;

useAppModelsPost;
useAppModelsUser;

classPostPolicy{
    publicfunctionupdate(?User $user, Post $post){
        return optional($user)->id === $post->user_id;
    }
}

Для определенных пользователей вы можете разрешить все действия в рамках конкретной политики. Для этого определите в политике метод before. Метод before будет выполнен перед любыми другими методами в политике, что даст вам возможность авторизовать действие до фактического вызова предполагаемого метода политики. Этот функционал чаще всего используется для авторизации администраторов приложения на выполнение любых действий:

useAppModelsUser;

publicfunctionbefore(User $user, $ability){
    if ($user->isAdministrator()) {
        returntrue;
    }
}

Если вы хотите отклонить все проверки авторизации для определенного типа пользователей, вы можете вернуть false из метода before. Если возвращается null, то проверка авторизации перейдет к методу политики.

Метод before класса политики не будет вызываться, если класс не содержит метода с именем, совпадающим с именем проверяемого полномочия.

Модель AppModelsUser приложения Laravel включает два полезных метода авторизации действий: can и cannot. Методы can и cannot получают имя действия, которое вы хотите авторизовать, и соответствующую модель. Например, давайте определим, авторизован ли пользователь для обновления переданной модели AppModelsPost. Обычно это делается в методе контроллера:

<?phpnamespaceAppHttpControllers;

useAppHttpControllersController;
useAppModelsPost;
useIlluminateHttpRequest;

classPostControllerextendsController{
    publicfunctionupdate(Request $request, Post $post){
        if ($request->user()->cannot('update', $post)) {
            abort(403);
        }

        
    }
}

Если для данной модели политика зарегистрирована, то метод can автоматически вызовет соответствующую политику и вернет логический результат. Если для модели не зарегистрирована политика, то метод can попытается вызвать шлюз на основе замыкания, соответствующий переданному имени действия.

Помните, что некоторые действия могут соответствовать методам политики, например create, которые не требуют экземпляра модели. В этих ситуациях вы можете передать имя класса методу can. Имя класса будет использоваться для определения того, какую политику использовать при авторизации действия:

<?phpnamespaceAppHttpControllers;

useAppHttpControllersController;
useAppModelsPost;
useIlluminateHttpRequest;

classPostControllerextendsController{
    publicfunctionstore(Request $request){
        if ($request->user()->cannot('create', Post::class)) {
            abort(403);
        }

        
    }
}

В дополнение к методам модели AppModelsUser, контроллеры Laravel, расширяющие базовый класс AppHttpControllersController, содержат полезный метод authorize.

Подобно методу can, этот метод принимает имя действия, которое вы хотите авторизовать, и соответствующую модель. Если действие не авторизовано, то метод authorize выбросит исключение IlluminateAuthAccessAuthorizationException, которое обработчик исключений Laravel автоматически преобразует в 403 HTTP-ответ:

<?phpnamespaceAppHttpControllers;

useAppHttpControllersController;
useAppModelsPost;
useIlluminateHttpRequest;

classPostControllerextendsController{
    publicfunctionupdate(Request $request, Post $post){
        $this->authorize('update', $post);

        
    }
}

Как обсуждалось ранее, некоторые методы политики, например create, не требуют экземпляра модели. В таких ситуациях вы должны передать имя класса методу authorize. Имя класса будет использоваться для определения того, какую политику использовать при авторизации действия:

useAppModelsPost;
useIlluminateHttpRequest;

publicfunctioncreate(Request $request){
    $this->authorize('create', Post::class);

    
}

Если вы используете ресурсные контроллеры, то вы можете использовать метод authorizeResource в конструкторе вашего контроллера. Этот метод добавит соответствующие определения посредника can к методам ресурсного контроллера.

Метод authorizeResource принимает имя класса модели в качестве своего первого аргумента и имя параметра маршрута / запроса, который будет содержать идентификатор модели, в качестве второго аргумента. Вы должны убедиться, что ваш ресурсный контроллер создан с использованием флага --model, чтобы он имел необходимые сигнатуры методов и объявления типов:

<?phpnamespaceAppHttpControllers;

useAppHttpControllersController;
useAppModelsPost;
useIlluminateHttpRequest;

classPostControllerextendsController{
    publicfunction__construct(){
        $this->authorizeResource(Post::class, 'post');
    }
}

Следующие методы контроллера будут сопоставлены соответствующим методам политики. Когда запросы направляются к методу контроллера, тогда перед выполнением метода контроллера будет автоматически вызываться соответствующий метод политики:

Метод контроллераМетод политики
indexviewAny
showview
createcreate
storecreate
editupdate
updateupdate
destroydelete

Вы можете использовать команду make:policy с параметром --model, чтобы сгенерировать класс политики для указанной модели: php artisan make:policy PostPolicy --model=Post.

Laravel содержит посредника, который может авторизовать действия до того, как входящий запрос достигнет ваших маршрутов или контроллеров. По умолчанию посреднику IlluminateAuthMiddlewareAuthorize назначается ключ can в вашем классе AppHttpKernel. Давайте рассмотрим пример использования посредника can для авторизации того, что пользователь может обновлять пост:

useAppModelsPost;

Route::put('/post/{post}', function(Post $post){
    
})->middleware('can:update,post');

В этом примере мы передаем посреднику can два аргумента. Первый – это имя действия, которое мы хотим авторизовать, а второй – параметр маршрута, передаваемый методу политики. В этом случае поскольку мы используем неявную привязку модели, то методу политики будет передана модель AppModelsPost. Если пользователь не авторизован для выполнения указанного действия, то посредник вернет ответ HTTP с кодом состояния 403.

Для удобства вы также можете прикрепить посредник can к своему маршруту, используя метод can:

useAppModelsPost;

Route::put('/post/{post}', function(Post $post){
    
})->can('update', 'post');

Опять же, некоторые методы политики, например create, не требуют экземпляра модели. В этих ситуациях вы можете передать имя класса посреднику. Имя класса будет использоваться для определения того, какую политику использовать при авторизации действия:

Route::post('/post', function(){
    
})->middleware('can:create,AppModelsPost');

Указание полного имени класса в определении посредника строки может стать обременительным. По этой причине вы можете присоединить посредник can к вашему маршруту, используя метод can:

useAppModelsPost;

Route::post('/post', function(){
    
})->can('create', Post::class);

При написании шаблонов Blade бывает необходимо отобразить часть страницы только в том случае, если пользователь авторизован для выполнения конкретного действия. Например, вы можете показать форму обновления поста в блоге, только если пользователь действительно уполномочен обновить сообщение. В этой ситуации вы можете использовать директивы @can и @cannot:

@can('update', $post)
    
@elsecan('create', AppModelsPost::class)
    
@else
    
@endcan

@cannot('update', $post)
    
@elsecannot('create', AppModelsPost::class)
    
@endcannot

Эти директивы являются удобными ярлыками выражений @if и @unless. Приведенные выше директивы @can и @cannot эквивалентны следующим выражениям:

@if (Auth::user()->can('update', $post))
    
@endif

@unless (Auth::user()->can('update', $post))
    
@endunless

Вы также можете определить, авторизован ли пользователь для выполнения любого из указанных в массиве действий. Для этого используйте директиву @canany:

@canany(['update', 'view', 'delete'], $post)
    
@elsecanany(['create'], AppModelsPost::class)
    
@endcanany

Как и большинство других методов авторизации, вы можете передать имя класса в директивы @can и @cannot, если для действия не требуется экземпляр модели:

@can('create', AppModelsPost::class)
    
@endcan

@cannot('create', AppModelsPost::class)
    
@endcannot

При авторизации действий с использованием политик вы можете передать массив в качестве второго аргумента различным функциям авторизации и помощникам. Первый элемент в массиве будет использоваться для определения того, какая политика должна быть вызвана, в то время как остальные элементы массива передаются как параметры методу политики и могут использоваться как дополнительный контекст при принятии решений об авторизации. Например, рассмотрим PostPolicy и следующее определение метода, содержащего дополнительный параметр $category:

publicfunctionupdate(User $user, Post $post, int $category){
    return $user->id === $post->user_id &&
           $user->canUpdateCategory($category);
}

При попытке определить, может ли аутентифицированный пользователь обновить указанный пост, мы можем вызвать этот метод политики следующим образом:

publicfunctionupdate(Request $request, Post $post){
    $this->authorize('update', [$post, $request->category]);

    
}

Аутентификация

Теперь, когда у вас есть маршруты и представления для имеющихся контроллеров аутентификации, вы готовы регистрировать и аутентифицировать новых пользователей своего приложения. Вы можете просто перейти по этим маршрутам в браузере, поскольку контроллеры аутентификации уже содержат логику (благодаря их типажам) для аутентификации существующих пользователей и сохранения новых пользователей в базе данных.

Изменение пути

Изменение защитника

Настройка хранилища/проверки ввода

Чтобы изменить требуемые поля для формы регистрации нового пользователя, или для изменения способа добавления новых пользователей в вашу базу данных, вы можете изменить класс RegisterController (для версии 5.2 — AuthController).

Внутри шаблонов blade

То же самое работает в отношении директивы Blade @can. Если для объекта, который указывается во втором аргументе, зарегистрирован класс политики, правило для проверки (метод класса политики) берется оттуда.

@can('update', $post)
	
@endcan

Другие методы аутентификации

Аутентификация экземпляра пользователя

Защита маршрутов

Посредник Route можно использовать, чтобы давать доступ к определённому маршруту только аутентифицированным пользователям.

Конечно, если вы используете контроллеры, вы можете вызвать метод PHPmiddleware() из конструктора контроллера, вместо присоединения его напрямую к определению маршрута:

Указание защитника

Маршрутизация

Laravel содержит AuthPasswordController, который содержит логику, необходимую для сброса пользовательских паролей.

Настройка

5.1 5.0

добавлено в


5.1

(19.06.2022)


5.0

(08.02.2022)

Социальная аутентификация

Для версии 5.2 и выше данный раздел перенесён на GitHub — прим. пер.

В дополнение к обычной аутентификации на основе формы, Laravel также предоставляет простой и удобный способ аутентификации с помощью провайдеров OAuth, используя Laravel Socialite. Socialite в настоящее время поддерживает аутентификацию через Facebook, Twitter, LinkedIn, Google, GitHub и Bitbucket.

Чтобы начать работать с Socialite, добавьте зависимость в свой файл composer.json:

confcomposer require laravel/socialite

Настройка

После установки библиотеки Socialite зарегистрируйте LaravelSocialiteSocialiteServiceProvider в своем конфигурационном файле config/app.php.

conf'providers' => [
  // Другие сервис-провайдеры...

  LaravelSocialiteSocialiteServiceProvider::class,
],

Также добавьте фасад Socialite в массив aliases в файле app:

conf'Socialite' => LaravelSocialiteFacadesSocialite::class,

Вам будет необходимо добавить учётные данные для сервисов OAuth, которые использует ваше приложение. Эти учётные данные должны быть помещены в ваш конфигурационный файл config/services.php и должны использовать ключ facebook, twitter, linkedin, google, github или bitbucket, в зависимости от провайдеров, которые необходимы вашему приложению. Например:

conf'github' => [
  'client_id' => 'your-github-app-id',
  'client_secret' => 'your-github-app-secret',
  'redirect' => 'http://your-callback-url',
],

Основы использования

Теперь можно аутентифицировать пользователей! Вам будут нужны два маршрута: один для перенаправления пользователя на провайдер OAuth, и второй для получения обратного вызова от провайдера после аутентификации. Мы обратимся к Socialite через фасадSocialite:

Метод PHPredirect() отвечает за отправку пользователя провайдеру OAuth, а метод PHPuser() читает входящий запрос и получает информацию пользователя от провайдера. Прежде чем перенаправить пользователя, вы можете также установить «области видимости» для запроса с помощью метода PHPscope(). Этот метод переопределит все существующие области видимости:

Само собой, вам необходимо определить маршруты для ваших методов контроллера:

Некоторые из провайдеров OAuth поддерживают необязательные параметры в запросе переадресации. Чтобы включить какие-либо необязательные параметры в запрос, вызовите метод PHPwith() с ассоциативным массивом:

Получение пользовательских данных

Когда у вас есть экземпляр пользователя, вы можете получить более подробную информацию о пользователе:

5.3 5.2

добавлено в


5.3

(28.01.2022)


5.2

(08.12.2022)

После регистрации провайдера методом PHPprovider(), вы можете переключиться на новый провайдер в файле настроек auth.php. Сначала определите «провайдера», который использует ваш новый драйвер:

conf'providers' => [
  'users' => [
    'driver' => 'riak',
  ],
],

И наконец, вы можете использовать этот провайдер в вашей настройке 'guards':

conf'guards' => [
  'web' => [
    'driver' => 'session',
    'provider' => 'users',
  ],
],

Настройка роутов

Первое добавим стандартные роуты для авторизации, используя команду

php artisan make:auth

Отлично давайте глянем какие роуты у нас есть, для этого воспользуемся командой

php artisan route:list

Вот вывод команды:

Я выделил роуты, которые относятся к авторизации, регистрации, выходу и восстановлению пароля. Теперь давайте добавим необходимые роты для авторизации и выхода из админки. Открываем файл routesweb.php

И добавляем следующие роуты:

Определение метода в классе

Помимо функции-замыкания, вы можете определить класс и метод для реализации правила:

$gate->define('update-post', 'Class@method');

Иногда вам нужно дать некому пользователю (например, админу) права на все операции. Для этого можно воспользоваться методом before, который запускается перед всеми остальными проверками:

Передача нескольких аргументов

Если в правило вам нужно передать не два аргумента (пользователь и некая сущность), а несколько, то в определении правила перечислите аргументы обычным способом:

Получение аутентифицированного пользователя

Вы можете обращаться к аутентифицированному пользователю через фасад Auth:

После сброса пароля

Когда вы определили маршруты и представления для сброса паролей пользователей, вы можете просто обратиться к данному маршруту через браузер (/password/reset). Встроенный в фреймворк PasswordController содержит логику отправки сообщений со ссылкой для сброса пароля, а также логику обновления паролей в базе данных.

После сброса пароля пользователь автоматически войдёт в приложение и будет перенаправлен к /home. Вы можете изменить этот путь задав свойство redirectTo в PasswordController:


По умолчанию ключи сброса пароля истекают через один час. Вы можете изменить это с помощью параметра expire в вашем файле config/auth.php.

Представления

5.1 5.0

добавлено в


5.1

(19.06.2022)


5.0

(08.02.2022)

Кроме определения маршрутов для PasswordController, вам надо предоставить представления, которые могут быть возвращены этим контроллером. Не волнуйтесь, мы предоставили примеры представлений, чтобы вам было легче начать. Вы можете изменить эти шаблоны под дизайн своего приложения.

Пример формы запроса ссылки для сброса пароля

Вам надо сделать HTML-представление для формы запроса сброса пароля. Это представление должно быть помещено в resources/views/auth/password.blade.php. Эта форма предоставляет единственное поле для ввода адреса e-mail, позволяя запросить ссылку для сброса пароля:

Когда пользователь подтвердит запрос на сброс пароля, он получит электронное письмо со ссылкой, которая указывает на метод PHPgetReset() (обычно расположенный по маршруту /password/reset) контроллера PasswordController. Вам надо создать представление для этого письма в resources/views/emails/password.blade.php. Представление получит переменную PHP$token, которая содержит ключ для сброса пароля, по которому происходит сопоставление пользователя с запросом сброса пароля. Вот пример представления для e-mail:

Пример формы сброса пароля

Когда пользователь переходит по ссылке из письма для сброса пароля, ему автоматически будет выведена форма сброса пароля. Это представление необходимо поместить в resources/views/auth/reset.blade.php.

Вот пример формы сброса пароля:

Прерывание всех проверок

Иногда вам нужно дать для некого пользователя (админа) разрешение на все права в данном классе политики. Для этого используйте метод before:

При помощи фасада gate

Фасад Gate автоматичести распознает тип объекта, который подается в качестве аргумента, и выбирает соответствующий класс политик, если таковой зарегистрирован. Имя правила для проверки, которое подается первым аргументом – это название метода класса политик, который будет вызывать Gate.

При помощи хелпера политики

При помощи глобального хелпера policy() можно получить инстанс класса политики, связанного с заданным объектом (в нешам случае – с объектом $post) и вызвать метод проверки правила авторизации напрямую:

Проверяем

Вы помните, что пользователей у нас нет. Пока нет. Переходим в корень нашего сайта:

Отлично все работает, проверим формы авторизации и регистрации. Работает. Теперь попробуем перейти в /home (по идее не должно пустить, так как мы не авторизовались). Отлично, перебросило на страницу авторизации.

Регистрация guard

Открываем configauth.php и добавляем следующий код

Регистрация политик

Как только класс политики создан, его надо зарегистрировать. Для этого добавьте его в свойство policies класса AuthServiceProvider вместе с сущностью, доступ к которой он призван регулировать:

Ручная аутентификация

Если вы не хотите использовать встроенные контроллеры аутентификации, вам нужно будет напрямую управлять аутентификацией пользователей, используя классы аутентификации Laravel. Не волнуйтесь, они не кусаются!

Мы будем работать со службами аутентификации Laravel через фасадAuth, поэтому нам надо не забыть импортировать фасад Auth в начале класса. Далее давайте посмотрим на метод PHPattempt():

Метод PHPattempt() принимает массив пар ключ/значение в качестве первого аргумента. Значения массива будут использованы для поиска пользователя в таблице базы данных.

Так, в приведённом выше примере пользователь будет получен по значению столбца email. Если пользователь будет найден, хешированный пароль, сохранённый в базе данных, будет сравниваться с хешированным значением password, переданным в метод через массив. Если два хешированных пароля совпадут, то для пользователя будет запущена новая аутентифицированная сессия.

Метод PHPattempt() вернёт true, если аутентификация прошла успешно. В противном случае будет возвращён false.

Метод PHPintended()«переадресатора» перенаправит пользователя к тому URL, к которому он обращался до того, как был перехвачен посредником аутентификации. В этот метод можно передать запасной URI, на случай недоступности требуемого пути.

Указание дополнительных условий

При необходимости вы можете добавить дополнительные условия к запросу аутентификации, помимо адреса e-mail и пароля. Например, можно проверить отметку «активности» пользователя:

Сброс и изменение паролей

В документации по ветке 5.3 и далее данный раздел статьи был вынесен в отдельную статью — Сброс пароля — прим. пер.

События


Laravel генерирует различные события в процессе аутентификации. Вы можете прикрепить слушателей к этим событиям в вашем EventServiceProvider:

5.3

добавлено в


5.3

(28.01.2022)

PHP

/**
* Сопоставления слушателя событий для вашего приложения.
*
* @var array
*/
protected $listen = [
'IlluminateAuthEventsRegistered' => [
'AppListenersLogRegisteredUser',
],
'IlluminateAuthEventsAttempting' => [
'AppListenersLogAuthenticationAttempt',
],
'IlluminateAuthEventsAuthenticated' => [
'AppListenersLogAuthenticated',
],
'IlluminateAuthEventsLogin' => [
'AppListenersLogSuccessfulLogin',
],
'IlluminateAuthEventsFailed' => [
'AppListenersLogFailedLogin',
],
'IlluminateAuthEventsLogout' => [
'AppListenersLogSuccessfulLogout',
],
'IlluminateAuthEventsLockout' => [
'AppListenersLogLockout',
],
];

Социальная аутентификация

Для версии 5.2 и выше данный раздел перенесён на GitHub — прим. пер.

Таблицы, миграции и модели.

Начнем с базы данных. В Laravel у нас есть две стандартные миграции:

Требования для базы данных

Большинство веб-приложений предоставляет пользователям возможность сбросить их забытые пароли. Вместо того, чтобы постоянно реализовывать это в каждом новом приложении, Laravel предлагает удобные методы для отправки писем о сбросе пароля и выполнении самого сброса.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *