Давайте создадим минимальный пример такого промежуточного программного обеспечения, чтобы вы могли оттуда его улучшить.
Из вашего объяснения я предполагаю, что у каждой книги будет свой пин-код. Вы можете изменить это поведение, если хотите что-то еще.
Сначала давайте создадим наши маршруты для просмотра / аутентификации книг:
routes/web.php
use Illuminate\Support\Facades\Route;
Route::group(['prefix' => 'book'], function () {
// view authenticated book
Route::get('{bookSlug}', 'BookController@view')->name('book.view');
// show book authenticate form
Route::get('{bookSlug}/authenticate', 'BookController@showAuth')->name('book.authenticate');
// handle user input, authenticate book
Route::post('{bookSlug}/authenticate', 'BookController@authenticate');
});
Давайте также добавим шаблон для параметра bookSlug
(обновите метод boot
, как показано):
app/Providers/RouteServiceProvider.php
class RouteServiceProvider extends ServiceProvider {
// ...
public function boot()
{
Route::pattern('bookSlug', '[A-Za-z0-9_-]+');
parent::boot();
}
// ...
}
Теперь давайте создадимпромежуточное программное обеспечение:
php artisan make:middleware CheckPin
Каждое промежуточное программное обеспечение имеет метод handle
, который позволяет ему что-то проверять и либо разрешать передачу запроса следующим (вызывая $next()
закрытие), либо останавливать обработку запроса, вызывая ошибкуили перенаправить на другой URL.
Здесь мы проверим статус аутентификации книги в сеансе. Он будет храниться там с помощью формы авторизации. Если книга еще не заверена, мы перенаправим на форму авторизации.
app/Http/Middleware/CheckPin.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Route;
class CheckPin {
public function handle($request, Closure $next)
{
$bookSlug = Route::current()->parameter('bookSlug');
// check whether book has been authenticated
// redirect to auth form otherwise
if(!session("books.$bookSlug")) {
return redirect()->route('book.authenticate', compact('bookSlug'));
}
return $next($request);
}
}
Мы должны зарегистрировать наше промежуточное ПО в Kernel.php
(обновите его, как показано на рисунке):
app/Http/Kernel.php
use App\Http\Middleware\CheckPin;
//...
class Kernel extends HttpKernel {
//...
protected $routeMiddleware = [
//...
'pin' => CheckPin::class, //
];
protected $middlewarePriority = [
//...
CheckPin::class,
];
//...
}
Давайте создадим наши простые представления. Создайте папку resources/views/book
и поместите в нее представления.
Просмотр для отображения содержимого книги:
resources/views/book/view.blade.php
<h1>View book → {{ $bookSlug }}</h1>
<p>Some content</p>
Просмотр для отображения формы авторизации книги:
resources/views/book/auth.blade.php
<h1>Authenticate → {{ $bookSlug }}</h1>
<form method="post" action="{{ route('book.authenticate', compact('bookSlug')) }}">
@csrf
<label for="pin">Enter pin:</label>
<input type="password" name="pin" id="pin" required autofocus />
<button class="submit">Authenticate</button>
@error('pin')
<p>
<i><b>Error:</b> {{ $message }}</i>
</p>
@enderror
</form>
И, наконец, давайте создадим контроллер книг, который будет отображать книги, создавать формы и обрабатывать ввод пользователя.
php artisan make:controller BookController
app/Http/Controllers/BookController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class BookController extends Controller {
public function __construct()
{
// "pin" middleware will protect all methods except @showAuth and @authenticate
$this->middleware('pin')->except(['showAuth', 'authenticate']);
}
function view(Request $request, string $bookSlug)
{
return view('book.view', compact('bookSlug'));
}
function showAuth(Request $request, string $bookSlug)
{
return view('book.auth', compact('bookSlug'));
}
// handles user input, checks for valid pin
// redirects to the authenticated book or back to the form
function authenticate(Request $request, string $bookSlug)
{
$pin = $request->input('pin');
// Check book pin here; for testing purpose: pin should equal book slug
if($pin === $bookSlug) {
session()->put("books.$bookSlug", 1);
return redirect()->route('book.view', compact('bookSlug'));
}
return redirect()->back()->withErrors(['pin' => ['Invalid pin']]);
}
}
Это работает так:
Когда пользователь открывает какую-то книгу, например book/funny
, она будет перенаправлена на book/funny/authenticate
, где они могут ввести пин-коди аутентифицировать книгу. Если пин-код действителен, то пользователь перенаправляется обратно на book/funny
URL, в противном случае отображается ошибка.
Вот и все. Вы можете расширить этот пример, чтобы он лучше соответствовал вашим потребностям: добавьте больше методов к BookController
, проверьте булавку из базы данных и т. Д.