Home > Mobile >  Laravel verify locale in url is same as user's locale from database
Laravel verify locale in url is same as user's locale from database

Time:01-06

So in my LocaleMiddleware class (which is located in the web group of the middleware), I have the following:

    if (Auth::check())
    {
        app()->setLocale($request->user()->getLocale()); // This just fetches the locale from the database for the given user
    }

And then it just returns the next request. However, there is a slight issue for example when logging in. I need to use the return redirect()->intended(); option. This poses a problem when I have for example the following route that I point to:

https://www.example.com/es/cervezas/dos

The English variant of this url would be:

https://www.example.com/en/beers/two

My routes look like this for example:

Route::name('user.')->prefix(app()->getLocale())->group(function () {
    Route::get(trans('routes.beers'), [BeersController::class, 'index'])->name('beers.index');
}

So in my routes I translate everything, and I also have slugs for each of my database models etc, which is why I always need to have the correct locale set but also I always need to have the correct locale in the url. If not I get not found exceptions when viewing specific model items or weird translations.

But one of the main problems is, when I go to the Spanish route for example (or any route for that matter in any language), after logging in, it will return the intended url/route, which will be the English one since en is the fallback locale.

So basically, what I was thinking is something along the lines of this, in my LocaleMiddleware class:

if (Auth::check())
{
    app()->setLocale($request->user()->getLocale());

    // Check if the segment locale is the same as the user locale
    // IF NOT, redirect them

    if(request()->segment(1) !== $request->user()->getLang())
    {
        return redirect()->route(request()->route()->getName()); // Not sure what to do here, doing this just creates an endless loop because the locale somehow was not updated yet it seems
    }
}

Any ideas for a solution for this, in the LocaleMiddleware or anywhere else? Or am I going about this the wrong way entirely? Any pointers are appreciated!

Edit:

Now in my LoginController I have the following:

protected function authenticated(Request $request, $user)
{
    app()->setlocale($user->getLocale());

    dd(app()->getLocale()); // This is the correct locale, `es` or `nl`

    dd(route('beers.index')); // This just always shows the English route
}

How come the app()->getLocale() shows the correct locale but the route is still always in the default locale? And of course, how to fix that?

CodePudding user response:

Usually you have access to the user in the login function before redirecting. In many of my projects there is an admin panel and I use the same default login endpoint. During the login process I check where the user is an admin or not and decide where to redirect him.

Here's an example of the store function in App\Http\Controllers\Auth\LoginController in a laravel 8 project:

/**
     * Handle an incoming authentication request.
     *
     * @param  \App\Http\Requests\Auth\LoginRequest  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(LoginRequest $request)
    {
        $request->authenticate();

        $request->session()->regenerate();

        if (Auth::user()->hasRole('admin')) {
            return redirect()->intended(RouteServiceProvider::ADMIN_HOME);
        }

        return redirect()->intended(RouteServiceProvider::HOME);
    }

So I believe that if you edit your redirection logic in the login controller it should work, because you have access the user, before you actually redirect him.

  • Related