如果没有给出重定向到默认语言环境并强化路由

Redirect to default locale if not given and fortify routes

我做了一个中间件来改变我网站的语言,但现在我面临两个问题,所以我希望你能帮助解决它们:

  1. 当用户键入 http://mywebiste/en/operations 时,该站点以英语显示,但如果我在 URL 上省略区域设置,则会抛出 404 页面。我的意图是使用默认区域设置或用户设置的最后一个区域设置自动重定向我的路由,例如,如果用户类型 http://mywebiste/operations,那么它应该直接转到 http://mywebiste/en/operations.

  2. 第二个问题是关于一些Fortify路线。一种情况是 2F 身份验证,我在设置语言切换器功能之前设法使用 Fortify 实现了双因素身份验证,但是现在当按钮“启用”2F 时它要求输入密码确认屏幕,但是因为它是在语言环境组它也给了我一个 404 页面 (http://mywebiste/user/confirm-password) 而不是 (http://mywebiste/en/user/confirm-password)。这同样适用于其他路由,所以我想操纵使用 Fortify 自动处理的重定向。

到目前为止我更改了相关代码...

我的中间件setLocale.php

    public function handle(Request $request, Closure $next)
    {
        if (empty($request->locale)) 
        {
            URL::defaults(['locale' => app()->getLocale()]);        
            return redirect(config('app.locale') . '/' . request()->path());
        }
        App::setLocale($request->locale);
        return $next($request);
    }

web.php

Route::group([
    'prefix' => '{locale?}',
    'where' => ['locale' => '[a-zA-Z]{2}'],
    'middleware' => 'setlocale'
], function () {
    // routes from fortify
    require(base_path('vendor/laravel/fortify/routes/routes.php'));

    Route::get('operations', 'EcmrController@view_records');

    //... other routes
});

Kernel.php

protected $middlewareGroups = [
        'web' => [
          ...
            \App\Http\Middleware\SetLocale::class,
        ],

        'api' => [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
       ...
        'setlocale' => \App\Http\Middleware\SetLocale::class,
    ];

    /**
     * The priority-sorted list of middleware.
     *
     * Manually copied from Illuminate\Foundation\Http\Kernel class and edited accordingly
     *
     * @var array
     */
    protected $middlewarePriority = [
       ...
        \App\Http\Middleware\SetLocale::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \Illuminate\Auth\Middleware\Authorize::class,
    ];

经过一番研究,我完成了第二题。

首先,我在 web.php 上复制了 Fortify 路由,并在 FortifyServiceProvider.php 上添加了以下代码。

public function register()
{
    Fortify::ignoreRoutes();
}

然后我不得不创建一个新的中间件来处理用户enable/disable 2F 函数之前的密码确认,并将其注册到Kernel.php。

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    // edited the password.confirm middleware to redirect to the locale + url 
    'password.confirm' => \App\Http\Middleware\RequirePassword::class,
    'setlocale' => \App\Http\Middleware\SetLocale::class,
    ...
];

这个新的 RequirePassword.php 中间件将用户重定向到路由 + 语言环境,因此它成功地转到了所需的路径。

Require Password我只复制编辑了handle方法

public function handle($request, Closure $next, $redirectToRoute = null)
{
    if ($this->shouldConfirmPassword($request)) {
        if ($request->expectsJson()) {
            return $this->responseFactory->json([
                'message' => 'Password confirmation required.',
            ], 423);
        }

        return $this->responseFactory->redirectGuest(
            $this->urlGenerator->route($redirectToRoute ?? 'password.confirm', app()->getLocale())
        );
    }

    return $next($request);
}

它帮助解决了我在使用 Fortify 和语言环境时遇到的其他问题,例如电子邮件验证。我也为它重复了同样的过程:

  1. 复制了中间件,
  2. 更改了句柄方法,
  3. 在 Kernel.php 上注册了新的。