Laravel Multi-Tenant Multi-Database Multi-Domain - Problem with default route - laravel

I'm studying about multi-tenant with Laravel and I'm having a problem with the routes. The main application works fine, however the main client domain (route / ) returns the 401 error configured in the middleware I created, but the other routes (login, register, etc) work perfectly.
If I put a prefix on the main application routes, then the / client route works normally, but I need the main application not to have a prefix since I want to use it to create the service submission and hiring system.
Anyone who has knowledge on this subject and can take a look at my code and help me find out why only the route is returning this error I will be very grateful.
If i access app.mydefaultapp works
If i access app.myclientapp doesn't works
If i access app.myclientapp/login(or any other route) works
https://pastebin.com/bHHux9sY

I solved the problem by creating a Provider with the same Middleware identification logic, and when accessing the main domain it dynamically loads the routes of the main domain.
$manager = app(ManagerTenant::class);
if ($manager->domainIsMain())
{
$this->registerTenantRoutes();
$this->registerTenantAdminRoutes();
}
https://pastebin.com/20SCsgfL

Related

Modify the URL generated with Route::apiResource without changing the name

I'm building a website where users can post ads : a VueJS app that requests routes on an Laravel API.
I have an AdController, with an Ad model, and my routing is done via stuff like :
Route::apiResource('ads', AdController::class)->only(['update', 'destroy']);
Route::apiResource('ads.photos', AdPhotoController::class)->only(['index']);
which generates routes like PUT "/ads/{ad}" or GET "/ads/{id}/photos"....
This works very well, and my VueJS app uses Ziggy to call the API by their route name
axios.get(route('ads.photos.index', id))
And... It still works flawlessly ! No problem at all, and I have a LOT of routes with a LOT of API calls.
Now my problem : we realised that URLs containing "ads" are blocked by adblockers. That completely shuts down all access to our website, and asking users to turn off the adblocker is NOT a solution.
I could change my routes to do something like
Route::apiResource('posts.photos', AdPhotoController::class)->only(['index']);
but I have a LOT of routes and I really don't want to rename everything, everywhere.
Is there an option to change apiResources generated URL, so 'ads.photos.index' would generate "/posts/{id}/photos" instead of "/ads/{id}/photos" ?

defining route with 'auth:web' middleware in laravel service provider boot() method

im using a package called https://github.com/garygreen/pretty-routes
there is line in its service provider boot() method (here the code)
it is defining a get route with middlewares from its config file(link to the code) I just added 'auth:web' to its config file but it seems the 'auth:web' middleware is called as soon as code reaches the line before Laravel bootstraps its session and etc. when the auth('web')->user() is yet null
What I can not understand is that I do the same exact thing (here the code)with laravel/telescope but it works. why ???
also changing :
Route::get(config('pretty-routes.url'), 'PrettyRoutes\PrettyRoutesController#show')
->name('pretty-routes.show')
->middleware(config('pretty-routes.middlewares'));
to :
$this->app['router']->get(config('pretty-routes.url'), 'PrettyRoutes\PrettyRoutesController#show')
->name('pretty-routes.show')
->middleware(config('pretty-routes.middlewares'));
in service provider seems to solve the problem and make this code behave like the way telescope package use 'auth:web' as middleware.
what's happening ?
You need to have the web middleware applied to any routes you need sessions for, which is what the default authentication system is using. When you apply the auth middleware without this it can't possibly resolve a user since there is no session to be authenticated against.
You need to apply the web middleware and then what ever other middleware you want:
'middlewares' => [
'web', 'auth:web',
],
If you look at the telescope example you provided you will see they also add the web middleware. So you didn't quite "do the same exact thing" as the telescope config.

Laravel Hyn Tenancy routes not defined on scheduler tasks

I am using Hyn Tenancy to handle multiple tenants on our Laravel application. Every tenant routes are defined at routes/tenants.php as specified by the package documentation and the system is working smoothly as expected.
But when I try to access tenant route via scheduler task, route not defined error pops up. I have setup tenant appropriately on the job execution and everything except route are working fine.
Find detailed issue here
Try to give name to the routes like below:
Route::get('/register', function () {
return view('register');
})->name('register');
Then call the route with the name.

Where to check if an User is logged in in a Laravel Application?

I've been using your advice and View::sharing all of my important data to all views. However, there is one issue I have encountered.
This code:
if(!Auth::guest()){
$user=Auth::user()->id;
}
else $user=0;
$temp=DB::select('query');
View::share('cartnumber', count($temp));
View::share('cartitems', $temp);
doesn't work when put in AppServiceProvider. Or better, it always sets $user=0, even if I am logged in. I thought it is because AppServiceProvider's boot function executes before the site checks if someone is logged in.
I then tried to use a BaseController with a construct function but that doesn't work either. The only solution that seems to work correctly is putting the code in every single Controller for every view! That actually works, which kind of confirms my theory.
But is there anywhere I can put this code without having to copy/paste it in every single Controller? Thanks in advance!
You'd likely want to put this code later in the request life cycle to guarantee an auth user because as others have mentioned middleware/session code has not occured during this part of the framework booting up. You could use a service class to call in all your controllers to avoid the copy pasting. Or If you'd like to achieve this using code in your service provider you could use a View Composer instead of a share this allows you to define a callback/or class that will be called right before the view is returned
view()->composer(['/uri-that-needs-data'], function ($view) {
if (Auth::check()) {
$cart = DB::query(...)->get();
$view->with('cartitems', $cart);
}
});
Check out https://laravel.com/docs/5.7/views#view-composers for more details.
Auth::user() will be empty until the session middleware has run.
The reason you can't access the user inside your service provider is because that code is run during the "bootstrapping" phase of the application lifecycle, when it's doing things like loading filesystem or cache drivers, long before the request is sent through response handlers (including middleware).
Once the application has been bootstrapped and all service providers
have been registered, the Request will be handed off to the router
for dispatching. The router will dispatch the request to a route or
controller, as well as run any route specific middleware.
Source: https://laravel.com/docs/5.7/lifecycle
If you don't want to copy/paste that code everywhere, then one place to put it is in custom route middleware. You can list it after the auth middleware to guarantee a logged-in user.
Edit: View composers are another really good option, as suggested by #surgiie. The reason these can be set up inside a service provider (unlike your example) is because the view composer registers a callback, but doesn't execute it until a much later stage in the application lifecycle.

Laravel Route Is not working because of Generic route

I am new to Laravel and learning just basic stuff. I am trying to create a new Route to create a user into database. So I created a Route like this -
Route::get('users/"create"', 'PagesController#create');
But I also have one Route for users trying to access their profile-
Route::get('users/{username}', 'PagesController#show');
Now when I try to access users/create it redirect me to show method instead of create method in controller. I am guessing this is because of generic nature of users/{username}. So my question is how to deal with such situation.
The order that you define routes is important. If you define your routes like this - in this order, it will work.
Route::get('users/create', 'PagesController#create');
Route::get('users/{username}', 'PagesController#show');
Note - I noticed you used 'users/"create"' - that is an error - it should be 'users/create' like in my example.
p.s. make sure you dont allow a user with the username called 'create' - or they will never be able to get to their profile page.

Resources