迁移到 Laravel、个性化 URL、所有请求的中间件、Auth::user 和 $errors 问题
Migration to Laravel, Vanity URLs, middleware for all requests, Auth::user and $errors issue
我创建了一个名为 PathParser 的中间件 class,它在每个请求上运行。目的是处理我们允许用户在我们的 Laravel vanilla PHP 应用程序中创建的 "vanity URL paths" 请求。例如:用户创建了一个 URL 路径,例如:http://example.com/i-love-this-place
PathParser 所做的是检查 404 响应,然后查看 URL 路径是否与我们的旧虚荣路径之一匹配。像这样:
class PathParser
{
public function handle($request, Closure $next, $guard = null)
{
$next_response = $next($request);
$status_code = $next_response->getStatusCode();
if ($status_code === 404) {
$script_url = $request->server("SCRIPT_URL");
$vanity_controller = new VanityController();
$found_vanity_id = Search::findVanityPath($script_url);
if (!empty($found_vanity_id)) {
$next_response = response()->make($vanity_controller->one($found_vanity_id));
}
}
return $next_response;
}
}
假设如下:
用户从未创建过会与任何路由冲突的URL路径
我必须支持一些现有的(pre-Laravel)虚荣URL在野外的路径- - 发布到社交媒体等。
在Kernel.php中,我有以下内容:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\PathParser::class,
//\Illuminate\Session\Middleware\StartSession::class,
//\Illuminate\View\Middleware\ShareErrorsFromSession::class,
];
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
在 $middleware 数组中,我尝试添加 StartSession 和 ShareErrorsFromSession(取消注释上面的两行),这部分起作用。 但是有两个主要问题:
- Auth::user 为空,即使对于登录用户对虚路径的请求也是如此
- 当用户提交 incorrect/invalid 信息
时,$errors 不再填充到表单提交(例如在注册和登录页面)
有没有一种方法既可以检查所有请求的路由,又可以获取经过身份验证的用户,同时保留 $errors?
我觉得我对请求生命周期的理解不够深入,无法成功。但也许有办法?
如果无法满足我的要求,则使用 302 重定向到标准前缀路径(例如 http://example.com/vanity/i-love-this -place) 是一个很好的解决方案。但我希望有另一种方法。
一些建议:
如果您不需要 auth/sessions/etc,那么您可以在应用程序的异常处理程序中处理 Symfony\Component\HttpKernel\Exception\NotFoundHttpException
异常。
在 app/Exceptions/Handler.php
中,将 render()
方法修改为如下所示:
public function render($request, Exception $e)
{
if ($e instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
// your code that returns a Response
}
return parent::render($request, Exception $e);
}
如果您确实需要 auth/sessions/etc,我建议您在路线文件末尾创建一个 "catchall" 路线。例如,作为 routes/web.php
文件的最后一行,输入:
Route::any('{catchall}', 'VanityController@handle')->where('catchall', '(.*)');
然后,在您的 VanityController
中,有一个 handle
方法,如下所示:
public function handle(Request $request, $url)
{
// logic to search and render your vanity page for $url
// if no vanity page was found:
throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
}
我创建了一个名为 PathParser 的中间件 class,它在每个请求上运行。目的是处理我们允许用户在我们的 Laravel vanilla PHP 应用程序中创建的 "vanity URL paths" 请求。例如:用户创建了一个 URL 路径,例如:http://example.com/i-love-this-place
PathParser 所做的是检查 404 响应,然后查看 URL 路径是否与我们的旧虚荣路径之一匹配。像这样:
class PathParser
{
public function handle($request, Closure $next, $guard = null)
{
$next_response = $next($request);
$status_code = $next_response->getStatusCode();
if ($status_code === 404) {
$script_url = $request->server("SCRIPT_URL");
$vanity_controller = new VanityController();
$found_vanity_id = Search::findVanityPath($script_url);
if (!empty($found_vanity_id)) {
$next_response = response()->make($vanity_controller->one($found_vanity_id));
}
}
return $next_response;
}
}
假设如下:
用户从未创建过会与任何路由冲突的URL路径
我必须支持一些现有的(pre-Laravel)虚荣URL在野外的路径- - 发布到社交媒体等。
在Kernel.php中,我有以下内容:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\PathParser::class,
//\Illuminate\Session\Middleware\StartSession::class,
//\Illuminate\View\Middleware\ShareErrorsFromSession::class,
];
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
在 $middleware 数组中,我尝试添加 StartSession 和 ShareErrorsFromSession(取消注释上面的两行),这部分起作用。 但是有两个主要问题:
- Auth::user 为空,即使对于登录用户对虚路径的请求也是如此
- 当用户提交 incorrect/invalid 信息 时,$errors 不再填充到表单提交(例如在注册和登录页面)
有没有一种方法既可以检查所有请求的路由,又可以获取经过身份验证的用户,同时保留 $errors?
我觉得我对请求生命周期的理解不够深入,无法成功。但也许有办法?
如果无法满足我的要求,则使用 302 重定向到标准前缀路径(例如 http://example.com/vanity/i-love-this -place) 是一个很好的解决方案。但我希望有另一种方法。
一些建议:
如果您不需要 auth/sessions/etc,那么您可以在应用程序的异常处理程序中处理 Symfony\Component\HttpKernel\Exception\NotFoundHttpException
异常。
在 app/Exceptions/Handler.php
中,将 render()
方法修改为如下所示:
public function render($request, Exception $e)
{
if ($e instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
// your code that returns a Response
}
return parent::render($request, Exception $e);
}
如果您确实需要 auth/sessions/etc,我建议您在路线文件末尾创建一个 "catchall" 路线。例如,作为 routes/web.php
文件的最后一行,输入:
Route::any('{catchall}', 'VanityController@handle')->where('catchall', '(.*)');
然后,在您的 VanityController
中,有一个 handle
方法,如下所示:
public function handle(Request $request, $url)
{
// logic to search and render your vanity page for $url
// if no vanity page was found:
throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
}