пятница, 30 июня 2017 г.

LARAVEL. КЛАССЫ-ПОСРЕДНИКИ

Классы-посредники или Middleware - фильтры обработки http-запросов.
Например, если пользователь не авторизован, то класс-посредник отправляет его на страницу авторизации.
Это некие слои, которые должен пройти запрос прежде чем он будет обработан. Если запрос не проходит, то он куда-либо перенаправляется.
Запросы по цепочке передаются от посредника к посреднику.


Во фреймворке поставляются некоторые стандартные посредники:
EncryptCookies - шифорвание информации, хранящейся в куках.
VerifyCsrfToken - защита от вредоносных аттак типа Csrf

Класс посредник можно создать через консоль.
php artisan make:middleware Mymiddleware

По этому адресу создался новый контроллер: app\Http\Middleware


<?php

namespace App\Http\Middleware;

use Closure;

class Mymiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}

Метод обработчик - handle. Он принимает 2 параметра: запрос пользователя, функция замыкания next.
Эта функция передает управление по цепочке к следующему классу-посреднику, если он имеется. И в конце передает управление к приложению.

Напишем проверку:
public function handle($request, Closure $next)
{
// проверим параметры, которые передаются в запросе
if($request->route('page') != 'pages') {
return redirect()->route('home');
}

return $next($request);
}

Идем в файл Http\Kernel.php и определим там наш посредник:
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'mymiddle' => \App\Http\Middleware\Mymiddleware::class,
];

Идем в маршрутизатор и регистрируем для данного маршрута класс-посредник:

Route::get('/articles', ['uses'=>'Admin\Core@getArticles', 'as'=>'articles']);

Route::get('/article/{page}',['middleware'=>'mymiddle','uses'=>'Admin\Core@getArticle','as'=>'article']);

В браузере набираем: http://tlaravel.loc/article/10
Нас перенаправляет на главную страницу: http://tlaravel.loc/

То нас не перенаправит.

Идем в контроллер App\Http\Controllers\Admin\Core.php
и в методе getArticle($id) выведем $id.
<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class Core extends Controller
{
// Возвращает список материалов:
public function getArticles() {

}

// Возвращает один материал:
public function getArticle($id) {
echo $id;
}
}

При обращении к http://tlaravel.loc/article/pages
У нас выведется: pages

В Kernel.php в protected $middlewareGroups мы можем объединять посредники в группу и использовать имя этой группы в маршрутизаторе.

Если в маршруте нужно указать несколько классов посредников, то формируем массив:
Route::get('/article/{page}',['uses'=>'Admin\Core@getArticle','as'=>'article', 'middleware'=>['mymiddle', 'auth']]);

Мы можем удалить ячейку middleware
Route::get('/article/{page}',['uses'=>'Admin\Core@getArticle','as'=>'article']);

В Kernel.php:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\Mymiddleware::class
];
Наш посредник будет отрабатывать для любого запроса пользователя.

Если мы обновим информацию, то у нас будет ошибка: Неверное перенаправление на странице

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

В app\Http\Middleware\Mymiddleware.php закомментируем проверку и выведем: echo 'Middle';


class Mymiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// проверим параметры, которые передаются в запросе
/* if($request->route('page') != 'pages') {
return redirect()->route('home');
} */
echo 'Middle';

return $next($request);
}
}

Обратимся: http://tlaravel.loc/
У нас выведется главная страница и слово Middle.

У нас выведется главная страница и слово Middlepages

Класс посредник отработал до обработки запроса и формирования ответа.

В app\Http\Middleware\Mymiddleware.php
public function handle($request, Closure $next)
{
// проверим параметры, которые передаются в запросе
/* if($request->route('page') != 'pages') {
return redirect()->route('home');
} */
//echo 'Middle';

$response = $next($request);

echo ' Middle';

return $response;
}
}

У нас выведется главная страница и слово pages Middle

В маршруте:
Route::get('/', ['as' => 'home', 'middleware'=>'mymidle', function () {
return view('welcome');
}]);


// Очень удобно использовать группы. Например, для формирования админки.
Route::group(['middleware'=>['web']], function() {

});

Посмотрим аутентификацию
В web.php
Route::get('/', ['as' => 'home', 'middleware'=>'auth', 'uses'=>'Admin\IndexController@show']);

Создадим контроллер в консоле:
php artisan make:controller Admin\IndexController

<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class IndexController extends Controller
{
public function show() {
return view('welcome');
}

}

Далее
В web.php
Route::get('/article/{page}',['uses'=>'Admin\Core@getArticle','as'=>'article'])->middleware(['mymiddle']);

В app\Http\Middleware\Mymiddleware.php
public function handle($request, Closure $next)
{
// проверим параметры, которые передаются в запросе
if($request->route('page') != 'pages') {
return redirect()->route('home');
}
return $next($request);
}

Запрос: http://tlaravel.loc/article/pages
Выводит: pages

В web.php
Route::get('/article/{page}',['uses'=>'Admin\Core@getArticle','as'=>'article']);

В App\Http\Controllers\Admin\Core.php
// В конструкторе мы также можем определить список посредников для работы.
public function __construct() {
$this->middleware('mymiddle');
}

Далее удалим конструктор.
В web.php
Если мы укажем двоеточие, то передадим параметр непосредственно в класс посредника.
Route::get('/article/{page}',['middleware'=>'mymiddle:admin', 'uses'=>'Admin\Core@getArticle','as'=>'article']);

В app\Http\Middleware\Mymiddleware.php
public function handle($request, Closure $next, $param)
{

if($request->route('page') != 'pages' &&
$param == 'admin') {
return redirect()->route('home');
}
return $next($request);
}

Обращаемся: http://tlaravel.loc/article/pages
При: http://tlaravel.loc/article/10 будет redirect

Если в web.php мы изменим
Route::get('/article/{page}',['middleware'=>'mymiddle:home', 'uses'=>'Admin\Core@getArticle','as'=>'article']);


То условие не выполнится и http://tlaravel.loc/article/10 не даст редиректа.

Комментариев нет:

Отправить комментарий

Materialize-css. Футер

Сделаем футер и прижмем к низу страницы. Документация: https://materializecss.com/footer.html