我已经阅读了Laravel的中间件文档,但是我感觉有些误会。
我想做的只是在每次查看图书之前进行身份验证。
例如如果我转到'\ book \ funnybook'redirect =>'\ book \ funnybook \ authenticate'(表示输入PIN码)
我遇到的问题是:
答案 0 :(得分:0)
在Controller中进行身份验证的后功能。类似下图
public function postPin(Request $request){
...
...
return Redirect::intended();
}
答案 1 :(得分:0)
让我们创建此类中间件的最小示例,以便您可以在那里进行改进。
根据您的解释,我认为每本书都会有自己的图钉。如果您需要其他功能,可以更改该行为。
首先,让我们创建用于查看/验证图书的路线:
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
添加更多方法,从数据库中检查书钉等。