1

I have a Laravel application, with a login form. I am using subdomains, for example: {{business_subdomain}}.laravel.test. The purpose of my application is create companies in my database, and make registered users login on their attached company and specific domain.

So in my web.php I declared the following:

Route::domain('{business_subdomain}.' . env('APP_URL'))->middleware(['business.subdomain'])->group(function ()

My database contains the following tables:
* Standard tables like users
* Businesses which contains id, name and subdomain
* Business_user which contains business_id and user_id

The business_id (business_user table) has a relationship with id (business table)
The user_id (business_user table) has a relationship with id (users table)

I created a middleware that checks the following:

$business = $request->user()->businesses->where('subdomain', $request->route('business_subdomain'))->first();

So the subdomain value (business table) must be the equal to the URL/route subdomain value, otherwise when you login, you will get an 403 page.

So what I want to achieve: When a user has an account, but is not attached to the right company/business, I want to display the standard authentication error: These credentials do not match our records.

I've tried to use the code in my middleware on the LoginController and override almost every function separately, but it didn't work.

Do I need to override Laravel authentication functions, do I need to create another middleware or use Guards?

The laravel authentication login order (the order the application uses for logging in a user) seems very confusing for me.

Maybe someone can provide me with more information or help me out!

I tried to use the code in my middleware on the LoginController and override almost every function separately, but it didn't work.

1 Answer 1

1

Sounds like you might be looking for multi-tenancy. There are a couple different packages available, both for single and multi-database setups.

Here are some very informative slides on the topic, specific to Laravel. And an excellent article for more detail.

We have a similar application with subdomain routing using torzer/awesome-landlord. The tenant package ensures that login will only search for users of the correct tenant.

To set the correct tenant we added a middleware (App is the tenant, in your case it would be Business):

    public function handle($request, Closure $next)
    {
        $subdomain = $this->getSubdomain($request->server('HTTP_HOST'));

        if ($subdomain) {
            $app = App::getBySlug($subdomain);

            abort_if(!$app, 404);

            $this->tenantManager->addTenant($app);
        } else {
            // empty or generic subdomain
            // this is OK as long as there is no user

            if ($user = $request->user()) {
                return $this->redirectToUserAppSubdomain($request, $user);
            }
        }

        return $next($request);
    }
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your really helpfull answer! But on which route do I need to provide this middleware, and how do I display the error on the login form when trying to log in with an account that is not in the company of the domain? Thank you in advance!
The middleware has to run on all requests. The package appends WHERE business_id = CURRENT_BUSINESS (CURRENT_BUSINESS is defined by addTenant()) to each select query of a model that belongs to a tenant (e.g. users). So the login form will automatically only look for users matching the email in the current app so it will fail if the entered email is in the wrong subdomain and show Laravel's default "user not found" error. Hope that's clear.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.