Авторизация (Laravel 5.4) — Laravel Framework Russian Community

Allows это единственный метод авторизации?

Нет, есть несколько методов.

  • allows — проверяет, может ли быть выполнено данное действие
  • denies — проверяет, запрещено ли данное действие.
  • check — проверяет, разрешены ли данные действие или массив действий.
  • any — проверяет, разрешено ли какое-либо из указанных действий
  • none — проверяет, запрещено ли какое-либо из указанных действий
  • authorize — проверяет, разрешено ли действие. если нет, то выбрасывает исключение IlluminateAuthAccessAuthorizationException
// use IlluminateAuthAccessResponse

Gate::allows(string $ability, $arguments = []): bool
Gate::denies(string $ability, $arguments = []): bool
Gate::check(array|string $abilities, $arguments = []): bool
Gate::any(array|string $abilities, $arguments = []): bool
Gate::none(array|string $abilities, $arguments = []): bool
Gate::authorize(string $ability, $arguments = []): Response

Аутентификация (laravel 8.x) — laravel framework russian community

Многие веб-приложения предоставляют своим пользователям возможность аутентифицироваться в приложении и «войти в систему». Реализация этого функционала в веб-приложениях может быть сложной и потенциально рискованной задачей. По этой причине Laravel стремится предоставить вам инструменты, необходимые для быстрой, безопасной и простой реализации аутентификации.

По своей сути средства аутентификации Laravel состоят из «охранников» и «провайдеров». Охранники определяют, как пользователи проходят проверку подлинности для каждого запроса. Например, Laravel поставляется с охранником session, который поддерживает состояние, используя хранилище сессий и файлы Cookies.

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

Файл конфигурации аутентификации вашего приложения находится в config/auth.php. Этот файл содержит несколько хорошо задокументированных вариантов для настройки поведения служб аутентификации Laravel.

Охранников и провайдеров не следует путать с «ролями» и «разрешениями». Чтобы узнать больше об авторизации действий пользователя с помощью разрешений, обратитесь к документации по авторизации.

Похожее:  Свердловэнергосбыт личный кабинет физического лица

Хотите быстро начать работу? Установите стартовый комплект приложения в новое приложение Laravel. После миграции базы данных перейдите в браузере по адресу /register или любому другому URL-адресу вашего приложения. Стартовые комплекты возьмут на себя создание всей вашей системы аутентификации!

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

По умолчанию Laravel содержит модель EloquentAppModelsUser в вашем каталоге app/Models. Эта модель использует по умолчанию драйвер аутентификации eloquent. Если ваше приложение не использует Eloquent, то вы можете использовать драйвер аутентификации database, основанный на построителе запросов Laravel.

При построении схемы базы данных для модели AppModelsUser убедитесь, что длина столбца password не менее 60 символов. Конечно, миграция таблицы пользователей, включенная в новые приложения Laravel, уже содержит столбец, длина которого превышает эту длину.

Кроме того, вы должны убедиться, что ваша таблица users (или эквивалентная) содержит столбец remember_token с параметрами VARCHAR(100) NULL. Этот столбец будет использоваться для хранения токена для пользователей, которые выбирают опцию «Запомнить меня» при входе в ваше приложение. Опять же, миграция таблицы пользователей по умолчанию, которая включена в новые приложения Laravel, уже содержит этот столбец.

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

Во-первых, рассмотрим, как работает аутентификация. При использовании веб-браузера пользователь вводит свое имя пользователя и пароль через форму входа. Если эти учетные данные верны, то приложение будет хранить информацию об аутентифицированном пользователе в сессии пользователя. Файл cookie, отправленный браузеру, содержит идентификатор сессии, чтобы последующие запросы к приложению могли связать пользователя с правильной сессией. После получения файла cookie сессии, приложение извлекает данные сессии на основе идентификатора сессии, отмечает, что аутентификационная информация была сохранена в сессии, и рассматривает пользователя как «аутентифицированного».

Когда удаленной службе необходимо пройти аутентификацию для доступа к API, файлы cookie обычно не используются для проверки подлинности, поскольку веб-браузер отсутствует. Вместо этого удаленная служба отправляет API-токен при каждом запросе к API. Приложение может проверять входящий токен по таблице допустимых API-токенов и «аутентифицировать» запрос как выполняемый пользователем, связанным с этим API-токеном.

Laravel содержит встроенные службы аутентификации и сессии, которые обычно доступны через фасады Auth и Session. Этот функционал обеспечивают аутентификацию на основе файлов Cookies для запросов, которые инициируются из веб-браузеров. Они предоставляют методы, которые позволяют вам проверять учетные данные пользователя и аутентифицировать пользователя. Кроме того, эти службы автоматически сохраняют необходимые данные аутентификации в сессии пользователя и выдают cookie сессии пользователя. В этой документации содержится информация о том, как использовать эти службы.

Стартовые комплекты приложения

Как уже было написано в этой документации, вы можете взаимодействовать с этими службами аутентификации напрямую, чтобы создать собственный слой аутентификации вашего приложения. Однако, чтобы помочь вам быстрее приступить к работе, мы выпустили бесплатные пакеты, которые обеспечивают надежную и современную основу всего слоя аутентификации. Это пакеты Laravel Breeze, Laravel Jetstream и Laravel Fortify.

Laravel Breeze – это простая, минимальная реализация всех возможностей аутентификации Laravel, включая вход в систему, регистрацию, сброс пароля, подтверждение электронной почты и подтверждение пароля. Слой представления Laravel Breeze состоит из простых шаблонов Blade, стилизованных с помощью Tailwind CSS. Чтобы начать использование, ознакомьтесь с документацией по стартовым комплектам. Breeze также предлагает вариант создания каркасов на основе Inertia с использованием Vue или React.

Laravel Fortify – это лишь серверная часть аутентификации для Laravel, которая реализует многие возможности, описанные в этой документации, включая аутентификацию на основе файлов cookie, а также другие возможности, такие как двухфакторная аутентификация и проверка электронной почты. Fortify обеспечивает серверную реализацию аутентификации для Laravel Jetstream, но может использоваться и независимо в сочетании с Laravel Sanctum для обеспечения одностраничных приложений (SPA) возможностью аутентификацией с Laravel.

Laravel Jetstream – это надежный стартовый комплект, который использует и предлагает службы аутентификации Laravel Fortify, но с красивым современным пользовательским интерфейсом на основе Tailwind CSS, Livewire и / или Inertia.js. Laravel Jetstream дополнительно включает поддержку двухфакторной аутентификации, поддержку команды, управление сеансами браузера, управление профилями и встроенную интеграцию с Laravel Sanctum для аутентификации токена API.

Laravel предлагает два дополнительных пакета, которые помогут вам в управлении токенами API и аутентификации запросов, сделанных с помощью токенов API: Passport и Sanctum. Обратите внимание, что эти библиотеки и встроенные в Laravel библиотеки аутентификации на основе файлов cookie не являются взаимоисключающими. Эти библиотеки в основном ориентированы на аутентификацию токена API, в то время как встроенные службы аутентификации ориентированы на web-аутентификацию на основе файлов cookie. Многие приложения будут использовать как встроенные службы аутентификации Laravel на основе файлов cookie, так и один из пакетов API-аутентификации Laravel.

Passport

Passport – это провайдер аутентификации OAuth2, предлагающий различные OAuth2 Grant Types («способы запросы»), которые позволяют вам выдавать различные типы токенов. В общем, это надежный и сложный пакет для аутентификации API. Однако большинству приложений не требуются сложный функционал, предлагаемый спецификацией OAuth2, что может сбивать с толку как пользователей, так и разработчиков. Кроме того, разработчики исторически не понимали, как аутентифицировать приложения SPA или мобильные приложения с помощью провайдеров аутентификации OAuth2, таких, как Passport.

Sanctum

В ответ на сложность OAuth2 и путаницу разработчиков мы решили создать более простой и оптимизированный пакет аутентификации, который мог бы обрабатывать как сторонние веб-запросы из браузера, так и запросы API через токены. Эта цель была реализована с выпуском Laravel Sanctum, который следует считать предпочтительным и рекомендуемым пакетом аутентификации для приложений, и который будет предлагать собственный веб-интерфейс в дополнение к API, или работать с одностраничным приложением (SPA), которое существует отдельно от серверного приложения Laravel, или приложений, предлагающих мобильный клиент.

Laravel Sanctum – это гибридный пакет аутентификации через Web / API, который может управлять всем процессом аутентификации вашего приложения. Это возможно, потому что когда приложения на основе Sanctum получают запрос, Sanctum сначала определяет, содержит ли запрос файл cookie сессии, который ссылается на аутентифицированную сессию. Sanctum выполняет это, вызывая встроенные службы аутентификации Laravel, которые мы обсуждали ранее. Если запрос не аутентифицируется с помощью файла cookie сессии, то Sanctum проверит запрос на наличие токена API. Если присутствует токен API, то Sanctum аутентифицирует запрос с помощью этого токена. Чтобы узнать больше об этом процессе, обратитесь к разделу «Как это работает» документации Sanctum.

Laravel Sanctum – это пакет API, который мы выбрали для включения в стартовый комплект Laravel Jetstream, потому что мы считаем, что он лучше всего подходит для большинства веб-приложений, требующих аутентификации.

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

Затем, если ваше приложение предлагает API, который будут использовать третьи стороны, то вы можете выбрать между Passport или Sanctum, чтобы обеспечить аутентификацию токена API для вашего приложения. В целом, по возможности следует отдавать предпочтение Sanctum, поскольку это простое и полное решение для аутентификации API, аутентификации SPA и мобильной аутентификации, включая поддержку «scopes» или «abilities».

Если вы создаете одностраничное приложение (SPA), которое будет работать с серверной частью Laravel, то вам следует использовать Laravel Sanctum. При использовании Sanctum вам потребуется либо самостоятельно реализовать свои собственные маршруты аутентификации на сервере, либо использовать Laravel Fortify как серверную службу аутентификации, которая предлагает маршруты и контроллеры для такого функционала, как регистрация, сброс пароля, подтверждение электронной почты и многое другое.

Passport можно выбрать, если вашему приложению необходим абсолютно весь функционал, предоставляемый спецификацией OAuth2.

И, если вы хотите быстро начать работу, то мы рады порекомендовать пакет Laravel Jetstream как быстрый способ запустить новое приложение Laravel, который уже использует предпочтительный стек аутентификации: встроенные службы аутентификации Laravel и Laravel Sanctum.

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

Во-первых, вы должны установить стартовый комплект Laravel. Наши текущие стартовые комплекты, Laravel Breeze и Laravel Jetstream, предлагают красиво оформленные отправные точки для интеграции аутентификации в ваше новое приложение Laravel.

Laravel Breeze – это минимальная и простая реализация всех возможностей аутентификации Laravel, включая вход в систему, регистрацию, сброс пароля, подтверждение электронной почты и подтверждение пароля. Слой представления Laravel Breeze состоит из простых шаблонов Blade, стилизованных с помощью Tailwind CSS.

Laravel Jetstream – это более надежный стартовый комплект для приложений, который включает поддержку построения вашего приложения с помощью Livewire или Inertia.js и Vue. Кроме того, Jetstream предлагает дополнительную поддержку двухфакторной аутентификации, команд, управления профилями, управления сеансами браузера, поддержки API через Laravel Sanctum, удаления аккаунтов и т. д.

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

useIlluminateSupportFacadesAuth;


$user = Auth::user();


$id = Auth::id();

В качестве альтернативы, как только пользователь аутентифицирован, вы можете получить доступ к аутентифицированному пользователю через экземпляр IlluminateHttpRequest. Помните, что объявленные типы зависимостей в методах вашего контроллера будут автоматически внедрены. Объявив объект IlluminateHttpRequest, вы можете получить доступ к аутентифицированному пользователю из любого метода контроллера вашего приложения с помощью метода user запроса:

<?phpnamespaceAppHttpControllers;

useIlluminateHttpRequest;

classFlightControllerextendsController{
    publicfunctionupdate(Request $request){
        
    }
}

Чтобы определить, аутентифицирован ли пользователь, выполняющий входящий HTTP-запрос, вы можете использовать метод check фасада Auth. Этот метод вернет true, если пользователь аутентифицирован:

useIlluminateSupportFacadesAuth;

if (Auth::check()) {
    
}

Несмотря на то, что можно определить, аутентифицирован ли пользователь с помощью метода check, вы обычно будете использовать посредника для проверки статуса аутентификации пользователя перед предоставлением пользователю доступа к определенным маршрутам / контроллерам. Чтобы узнать больше об этом, ознакомьтесь с документацией по защите маршрутов.

Посредник маршрута используется для того, чтобы разрешить только аутентифицированным пользователям доступ к указанному маршруту. Laravel содержит посредник auth, который ссылается на класс IlluminateAuthMiddlewareAuthenticate. Поскольку этот посредник уже зарегистрирован в HTTP-ядре вашего приложения, все, что вам нужно сделать, это задать посредника к определению маршрута:

Route::get('/flights', function(){
    
})->middleware('auth');

Когда посредник auth обнаруживает неаутентифицированного пользователя, он перенаправляет пользователя на именованный маршрутlogin. Вы можете изменить это поведение, обновив функцию redirectTo в файле app/Http/Middleware/Authenticate.php вашего приложения:

protectedfunctionredirectTo($request){
    return route('login');
}

При задании посредника auth маршруту вы также можете указать, какой «охранник» должен использоваться для аутентификации пользователя. Указанный охранник должен соответствовать одному из указанных в массиве guards конфигурационного файла config/auth.php:

Route::get('/flights', function(){
    
})->middleware('auth:admin');

Если вы используете стартовые комплекты Laravel Breeze или Laravel Jetstream, то к попыткам входа в систему будет автоматически применяться ограничение. По умолчанию, если пользователь не сможет предоставить правильные учетные данные после нескольких попыток, то он не сможет войти в систему в течение одной минуты. Частота попыток уникальна для имени пользователя / адреса электронной почты и в совокупности с IP-адресом.

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

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

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

<?phpnamespaceAppHttpControllers;

useIlluminateHttpRequest;
useIlluminateSupportFacadesAuth;

classLoginControllerextendsController{
    publicfunctionauthenticate(Request $request){
        $credentials = $request->validate([
            'email' => ['required', 'email'],
            'password' => ['required'],
        ]);

        if (Auth::attempt($credentials)) {
            $request->session()->regenerate();

            return redirect()->intended('dashboard');
        }

        return back()->withErrors([
            'email' => 'The provided credentials do not match our records.',
        ]);
    }
}

Метод attempt принимает массив пар ключ / значение в качестве своего первого аргумента. Значения в массиве будут использоваться для поиска пользователя в таблице базы данных. Итак, в приведенном выше примере пользователь будет извлечен по значению столбца email. Если пользователь найден, то хешированный пароль, хранящийся в базе данных, будет сравниваться со значением password, переданным в метод через массив. Вы не должны хешировать значение пароля входящего запроса, поскольку фреймворк автоматически хеширует это значение, прежде чем сравнивать его с хешированным паролем в базе данных. Если два хешированных пароля совпадают, то для пользователя будет запущена аутентифицированная сессия.

Помните, что службы аутентификации Laravel будут получать пользователей из вашей базы данных на основе конфигурации провайдера вашего охранника аутентификации. В конфигурационном файле config/auth.php по умолчанию указан провайдер пользователей Eloquent, и ему дано указание использовать модель AppModelsUser при получении пользователей. Вы можете изменить эти значения в своем файле конфигурации в зависимости от потребностей вашего приложения.

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

Метод intended экземпляра IlluminateRoutingRedirector Laravel, будет перенаправлять пользователя на URL-адрес, к которому он пытался получить доступ, прежде чем он будет перехвачен посредником аутентификации. Этому методу может быть предоставлен резервный URI в случае, если адрес, переданный методу intended недоступен.

При желании вы также можете добавить дополнительные условия запроса к запросу аутентификации в дополнение к электронной почте и паролю пользователя. Для этого мы можем просто добавить условия запроса в массив, переданному методу attempt. Например, мы можем проверить, что пользователь отмечен как «активный»:

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
    
}

В этих примерах email не является обязательным параметром, он просто используется в качестве примера. Вы должны использовать любое имя столбца, равнозначное «имени пользователя» в таблице базы данных.

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

Имя охранника, переданное методу guard, должно соответствовать одному из настроенных в вашем файле конфигурации auth.php охраннику:

if (Auth::guard('admin')->attempt($credentials)) {
    
}

Многие веб-приложения содержат флажок «Запомнить меня» в форме входа. Если вы хотите реализовать функционал «Запомнить меня» в своем приложении, то вы можете передать логическое значение в качестве второго аргумента метода attempt.

Когда это значение равно true, Laravel будет поддерживать аутентификацию пользователя неопределенно долго или до тех пор, пока он не выйдет из системы вручную. Ваша таблица users должна включать столбец remember_token, который будет использоваться для хранения токена функционала «Запомнить меня». Миграция таблицы пользователей, входящая в новые приложения Laravel, уже содержит этот столбец:

useIlluminateSupportFacadesAuth;

if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
    
}

Если вам нужно задать экземпляр существующего пользователя в качестве текущего аутентифицированного, то вы можете передать этот экземпляр методу login фасада Auth. Переданный экземпляр пользователя должен быть реализацией контрактаIlluminateContractsAuthAuthenticatable. Модель AppModelsUser, поставляемая с Laravel, уже реализует этот интерфейс. Этот метод аутентификации полезен, когда у вас уже есть экземпляр пользователя, например, сразу после того, как пользователь регистрируется в вашем приложении:

useIlluminateSupportFacadesAuth;

Auth::login($user);

Вы можете передать логическое значение в качестве второго аргумента метода login. Это значение указывает, требуется ли для аутентифицированной сессии функциональность «Запомнить меня». Помните, это означает, что сессия будет аутентифицироваться бесконечно или до тех пор, пока пользователь вручную не выйдет из приложения:

Auth::login($user, $remember = true);

При необходимости вы можете указать охранника аутентификации перед вызовом метода login:

Auth::guard('admin')->login($user);

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

Auth::loginUsingId(1);

Вы можете передать логическое значение в качестве второго аргумента метода loginUsingId. Это значение указывает, требуется ли для аутентифицированной сессии функциональность «Запомнить меня». Помните, это означает, что сессия будет аутентифицироваться бесконечно или до тех пор, пока пользователь вручную не выйдет из приложения:

Auth::loginUsingId(1, $remember = true);

Вы можете использовать метод once для аутентификации пользователя в приложении только для одного запроса. При вызове этого метода не будут использоваться сессии или файлы cookie:

if (Auth::once($credentials)) {
    
}

Basic HTTP-аутентификация обеспечивает быстрый способ аутентификации пользователей вашего приложения без создания специальной «страницы входа». Для начала задайте маршруту посредникаauth.basic. Посредник auth.basic поставляется с Laravel, поэтому вам не нужно его определять:

Route::get('/profile', function(){
    
})->middleware('auth.basic');

После того как посредник задан маршруту, вам будет автоматически предложено ввести учетные данные при доступе к маршруту в вашем браузере. По умолчанию посредник auth.basic предполагает, что столбец email в вашей таблице базы данных users является его «логином».

Если вы используете PHP FastCGI и Apache для своего приложения Laravel, то аутентификация HTTP Basic может работать некорректно. Чтобы исправить эти проблемы, в файл .htaccess вашего приложения можно добавить следующие строки:

RewriteCond %{HTTP:Authorization} ^(. )$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Вы также можете использовать Basic HTTP-аутентификацию без задания cookie идентификатора пользователя в сессии. Это в первую очередь полезно, если вы решите использовать HTTP-аутентификацию для аутентификации запросов к API вашего приложения. Для этого определите посредника, который вызывает метод onceBasic. Если метод onceBasic не возвращает ответа, то запрос может быть передан дальше в приложение:

<?phpnamespaceAppHttpMiddleware;

useIlluminateSupportFacadesAuth;

classAuthenticateOnceWithBasicAuth{
    publicfunctionhandle($request, $next){
        return Auth::onceBasic() ?: $next($request);
    }

}

Затем зарегистрируйте посредника и задайте его маршруту:

Route::get('/api/user', function(){
    
})->middleware('auth.basic.once');

Чтобы обеспечить пользователю возможность выхода из вашего приложения, вы можете использовать метод logout фасада Auth. Это удалит информацию аутентификации из сессии пользователя, так что последующие запросы не будут аутентифицированы.

В дополнение к вызову метода logout рекомендуется аннулировать сессию пользователя и повторно сгенерировать его токен CSRF. После выхода пользователя из системы вы обычно перенаправляете пользователя в корень вашего приложения:

useIlluminateHttpRequest;
useIlluminateSupportFacadesAuth;

publicfunctionlogout(Request $request){
    Auth::logout();

    $request->session()->invalidate();

    $request->session()->regenerateToken();

    return redirect('/');
}

Laravel также предлагает механизм для «выхода» пользователя и аннулирования сессий, активных на других устройствах, без аннулирования сессии на его текущем устройстве. Этот функционал обычно используется, когда пользователь меняет или обновляет свой пароль, и вы хотите аннулировать сессии на других устройствах, сохранив аутентификацию текущего устройства.

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

'web' => [
    
    IlluminateSessionMiddlewareAuthenticateSession::class,
    
],

Затем вы можете использовать метод logoutOtherDevices фасада Auth. Этот метод требует, чтобы пользователь подтвердил свой текущий пароль, который ваше приложение должно принять через форму ввода:

useIlluminateSupportFacadesAuth;

Auth::logoutOtherDevices($currentPassword);

Когда вызывается метод logoutOtherDevices, другие сессии пользователя будут полностью аннулированы, то есть он будет «отключен» от всех охранников, которым он ранее был аутентифицированы.

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

В следующей документации обсуждается, как напрямую интегрироваться с функционалом подтверждения пароля Laravel; однако, если вы хотите начать работу быстрее, то стартовые комплекты Laravel уже включают поддержку этого функционала!

После подтверждения пароля пользователю не будет предлагаться повторно подтвердить пароль в течение трех часов. Однако вы можете настроить время, по истечении которого пользователю будет предложено повторно ввести пароль, изменив значение параметра конфигурации password_timeout в файле конфигурации config/auth.php вашего приложения.

Сначала мы определим маршрут для отображения шаблона формы с запросом у пользователя подтверждения своего пароля:

Route::get('/confirm-password', function(){
    return view('auth.confirm-password');
})->middleware('auth')->name('password.confirm');

Как и следовало ожидать, шаблон, возвращаемый этим маршрутом, должен иметь форму, содержащую поле password. Кроме того, добавьте текст, который объясняет, что пользователь входит в защищенный раздел приложения и должен подтвердить свой пароль.

Затем мы определим маршрут, который будет обрабатывать запрос формы из шаблона «подтвердить пароль». Этот маршрут будет отвечать за проверку пароля и перенаправление пользователя к месту назначения:

useIlluminateHttpRequest;
useIlluminateSupportFacadesHash;
useIlluminateSupportFacadesRedirect;

Route::post('/confirm-password', function(Request $request){
    if (! Hash::check($request->password, $request->user()->password)) {
        return back()->withErrors([
            'password' => ['The provided password does not match our records.']
        ]);
    }

    $request->session()->passwordConfirmed();

    return redirect()->intended();
})->middleware(['auth', 'throttle:6,1']);

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

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

Route::get('/settings', function(){
    
})->middleware(['password.confirm']);

Route::post('/settings', function(){
    
})->middleware(['password.confirm']);

Вы можете определить своих собственных охранников аутентификации, используя метод extend фасада Auth. Вы должны разместить свой вызов метода extend внутри поставщика служб. Поскольку Laravel уже содержит AuthServiceProvider, мы можем разместить код в этом поставщике:

<?phpnamespaceAppProviders;

useAppServicesAuthJwtGuard;
useIlluminateFoundationSupportProvidersAuthServiceProviderasServiceProvider;
useIlluminateSupportFacadesAuth;

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

        Auth::extend('jwt', function($app, $name, array $config){
            returnnew JwtGuard(Auth::createUserProvider($config['provider']));
        });
    }
}

Как вы можете видеть в приведенном выше примере, замыкание, переданное методу extend, должно возвращать реализацию IlluminateContractsAuthGuard. Этот интерфейс содержит несколько методов, которые вам необходимо реализовать для определения своего охранника. После того как ваш охранник был определен, вы можете ссылаться на него в конфигурации guards конфигурационного файла config/auth.php:

'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

Самый простой способ реализовать собственную систему аутентификации на базе HTTP-запросов – использовать метод Auth::viaRequest. Этот метод позволяет быстро определить процесс аутентификации с помощью одного замыкания.

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

useAppModelsUser;
useIlluminateHttpRequest;
useIlluminateSupportFacadesAuth;

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

    Auth::viaRequest('custom-token', function(Request $request){
        return User::where('token', $request->token)->first();
    });
}

После того как ваш драйвер аутентификации был определен, вы можете настроить его как драйвер в конфигурации guards конфигурационного файла config/auth.php:

'guards' => [
    'api' => [
        'driver' => 'custom-token',
    ],
],

Если вы не используете традиционную реляционную базу данных для хранения своих пользователей, то вам нужно будет расширить Laravel своим собственным провайдером аутентификации пользователей. Мы будем использовать метод provider фасада Auth для определения собственного провайдера пользователей. Провайдер пользователей должен вернуть реализацию IlluminateContractsAuthUserProvider:

<?phpnamespaceAppProviders;

useAppExtensionsMongoUserProvider;
useIlluminateFoundationSupportProvidersAuthServiceProviderasServiceProvider;
useIlluminateSupportFacadesAuth;

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

        Auth::provider('mongo', function($app, array $config){
            returnnew MongoUserProvider($app->make('mongo.connection'));
        });
    }
}

После того как вы зарегистрировали провайдера с помощью метода provider, вы можете переключиться на нового провайдера пользователей в конфигурационном файле config/auth.php. Сначала определите провайдера, который использует ваш новый драйвер:

'providers' => [
    'users' => [
        'driver' => 'mongo',
    ],
],

Наконец, вы можете указать этого провайдера в своей конфигурации guards:

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

Реализации IlluminateContractsAuthUserProvider отвечают за получение реализации IlluminateContractsAuthAuthenticatable из системы постоянного хранения, такой как MySQL, MongoDB и т. д. Эти два интерфейса позволяют механизмам аутентификации Laravel продолжать функционировать независимо от того, как хранятся пользовательские данные или какой тип класса используется для представления аутентифицированного пользователя.

Давайте посмотрим на контракт IlluminateContractsAuthUserProvider:

<?phpnamespaceIlluminateContractsAuth;

interfaceUserProvider{
    publicfunctionretrieveById($identifier);
    publicfunctionretrieveByToken($identifier, $token);
    publicfunctionupdateRememberToken(Authenticatable $user, $token);
    publicfunctionretrieveByCredentials(array $credentials);
    publicfunctionvalidateCredentials(Authenticatable $user, array $credentials);
}
  • Метод retrieveById обычно принимает ключ, представляющий пользователя, такой как автоинкрементный идентификатор из базы данных MySQL. Реализация Authenticatable, соответствующая идентификатору, должна быть получена и возвращена методом.

  • Метод retrieveByToken извлекает пользователя по его уникальному идентификатору $identifier и $token, обычно хранящимся в столбце remember_token базы данных. Как и в предыдущем методе, этот метод должен вернуть реализацию Authenticatable соответствующую значению токена.

  • Метод updateRememberToken обновляет remember_token экземпляра $user новым $token. Новый токен назначается пользователям при успешной попытке аутентификации с отмеченным флажком «Запомнить меня» или когда пользователь выходит из системы.

  • Метод retrieveByCredentials принимает массив учетных данных, переданный методу Auth::attempt при попытке аутентификации в приложении. Затем метод должен «запросить» у постоянного хранилища пользователя, соответствующего этим учетным данным. Как правило, этот метод запускает запрос с условием WHERE, который ищет запись пользователя с «именем пользователя», равнозначным $credentials['имя пользователя']. Метод должен возвращать реализацию Authenticatable. Этот метод не должен пытаться выполнить проверку пароля или аутентификацию.

  • Метод validateCredentials должен сравнивать переданный $user с $credentials для аутентификации пользователя. Например, этот метод обычно использует метод Hash::check для сравнения значения $user->getAuthPassword() со значением $credentials['password']. Этот метод должен возвращать true или false, указывая, действителен ли пароль.

Теперь, когда мы изучили каждый из методов UserProvider, давайте взглянем на контракт Authenticatable. Помните, что провайдеры пользователей должны возвращать реализации этого интерфейса из методов retrieveById, retrieveByToken, и retrieveByCredentials:

<?phpnamespaceIlluminateContractsAuth;

interfaceAuthenticatable{
    publicfunctiongetAuthIdentifierName();
    publicfunctiongetAuthIdentifier();
    publicfunctiongetAuthPassword();
    publicfunctiongetRememberToken();
    publicfunctionsetRememberToken($value);
    publicfunctiongetRememberTokenName();
}

Этот интерфейс прост. Метод getAuthIdentifierName должен возвращать имя поля «первичного ключа» пользователя, а метод getAuthIdentifier должен возвращать «первичный ключ» пользователя. При использовании серверной части MySQL это, вероятно, будет автоинкрементный первичный ключ, присваиваемый записи пользователя. Метод getAuthPassword должен возвращать хешированный пароль пользователя.

Этот интерфейс позволяет системе аутентификации работать с любым классом User, независимо от того, какой ORM или уровень абстракции хранилища вы используете. По умолчанию Laravel включает класс AppModelsUser в каталог app/Models, который реализует этот интерфейс.

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

protected $listen = [
    'IlluminateAuthEventsRegistered' => [
        'AppListenersLogRegisteredUser',
    ],

    'IlluminateAuthEventsAttempting' => [
        'AppListenersLogAuthenticationAttempt',
    ],

    'IlluminateAuthEventsAuthenticated' => [
        'AppListenersLogAuthenticated',
    ],

    'IlluminateAuthEventsLogin' => [
        'AppListenersLogSuccessfulLogin',
    ],

    'IlluminateAuthEventsFailed' => [
        'AppListenersLogFailedLogin',
    ],

    'IlluminateAuthEventsValidated' => [
        'AppListenersLogValidated',
    ],

    'IlluminateAuthEventsVerified' => [
        'AppListenersLogVerified',
    ],

    'IlluminateAuthEventsLogout' => [
        'AppListenersLogSuccessfulLogout',
    ],

    'IlluminateAuthEventsCurrentDeviceLogout' => [
        'AppListenersLogCurrentDeviceLogout',
    ],

    'IlluminateAuthEventsOtherDeviceLogout' => [
        'AppListenersLogOtherDeviceLogout',
    ],

    'IlluminateAuthEventsLockout' => [
        'AppListenersLogLockout',
    ],

    'IlluminateAuthEventsPasswordReset' => [
        'AppListenersLogPasswordReset',
    ],
];

Генерирование политик

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

Вы можете сгенерировать политику с помощью artisan-команды shmake:policy. Сгенерированная политика будет помещена в каталог app/Policies. Если такого каталога нет в вашем приложении, Laravel создаст его:

shphp artisan make:policy PostPolicy

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

shphp artisan make:policy PostPolicy --model=Post

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

Определение, аутентифицирован ли пользователь

Чтобы определить, что пользователь уже вошёл в ваше приложение, вы можете использовать метод check фасада Auth, который вернёт true, если пользователь аутентифицирован:

useIlluminateSupportFacadesAuth;

if (Auth::check()) {
    
}

Хотя и возможно определить аутентифицирован ли пользователь, используя метод check, обычно вы будете использовать посредников для проверки был ли пользователь аутентифицирован ранее, позволяя этому пользователю получать доступ к определенным роутам / контроллерам. Для получения дополнительной информации смотрите документацию о защите роутов.

Чтобы давать доступ к определённому роуту только аутентифицированным пользователям можно использовать специальный посредник (middleware). Laravel поставляется с посредником auth, который определён в IlluminateAuthMiddlewareAuthenticate.

Route::get('profile', function(){
    
})->middleware('auth');

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

publicfunction__construct(){
    $this->middleware('auth');
}

Создание системы аутентификации вместе с созданием приложения

На этапе создания приложения вы можете указать флаг –auth и инсталлятор сразу добавит систему аутентификации:

laravel new blog --auth

Как было упомянуто в предыдущем разделе, команда php artisan ui vue –auth из пакета laravel/ui создаст все необходимые вам шаблоны для аутентификации и поместит их в директорию resources/views/auth.

Команда ui также создаст директорию resources/views/layouts, содержащую основной макет для вашего приложения. Все эти макеты используют CSS-фреймворк Bootstrap, но вы можете изменять их как угодно.

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

Указание гварда

Во время прикрепления посредника auth к роуту, вы можете также указать, какой гвард должен быть использован для выполнения аутентификации. Указанный гвард должен соответствовать одному из ключей в массиве guards вашего конфига auth.php:

publicfunction__construct(){
    $this->middleware('auth:api');
}

Особо важные места сайта (изменение критичных настроек – например, платёжной информации) можно защитить путём повторного запроса пароля у пользователя.

Для этого защитите роут или группу роутов посредником password.confirm . При заходе на этот урл будет произведён редирект на промежуточную страницу с формой ввода пароля.

Route::get('/settings/security', function(){
    
})->middleware(['auth', 'password.confirm']);

После успешного ввода пароля произойдёт редирект на защищаемый роут. При повтором входе на этот роут пароль не будет спрашиваться в течении трёх часов. Вы можете изменить это время путём редактирования опции auth.password_timeout в конфиге.

Если вы используете встроенный в Laravel класс LoginController, трейт IlluminateFoundationAuthThrottlesLogins уже будет включён в ваш контроллер. По умолчанию пользователь не сможет войти в приложение в течение одной минуты, если он несколько раз указал неправильные данные для входа. Ограничение происходит отдельно для имени пользователя/адреса e-mail и его IP-адреса.

Вы можете написать свои контроллеры аутентификации пользователей, не пользоваться теми, что генерирует фреймворк, если по какой-то причине они вас не устраивают. Для этого вам нужно использовать в своих контроллерах классы аутентификации Laravel. Не волнуйтесь, это просто.

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

Через шаблоны blade

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

Эти директивы — удобный короткий вариант для написания операторов PHP@if и PHP@unless.

Операторы PHP@can и PHP@cannot из приведённого примера можно перевести соответственно в следующие операторы:

Действия, не требующие моделей

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

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

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