Two separate Inertia.js applications on one Laravel - laravel

Hello Masters of the Javascript and Laravel.
I'm wondering if it's possible to make two separate inertia.js applications in one Laravel application.
I'm making a SaaS style application, where there will be a front facing part and a backoffice part.
This will be split in two domains (or more), using the same Laravel/Octane application. This works.
However, the Ziggy routes from the backoffice also show up in the front facing application.
There's of course a security risk that these are included, in the Ziggy data. Also transferring the routes from the admin part creates unnecessary traffic, since the routes are transferred with every request with inertia. The backoffice will have a lot more routes than the relatively simple frontend.
Any idea on how this could be structured so the Ziggy data is split in two, while it still being one application?

I dont think this would be possible or if it is, it would be too complex setup since Interia relies with Laravel routing and when you are passing Laravel back to interia you'd have to determine which of that Inertia App you'd push the data.
I think the better approach for this is to just create domain group routes if you need multiple domains support, then create a persistent layout in the front-end which you can use for public/front-end area and admin area. You can just use Laravel Jetstream with Vue+Inertia.
I dont really see any reason why you would need different front-end application, but if you really do, I think you better just set-up Laravel for API routes so you can set-up different application for the front-end.

I ended up doing this in HandleInertiaRequests middleware
/**
* Define the props that are shared by default.
*
* #return array<string, mixed>
*/
public function share(Request $request): array
{
$ziggyObj = (new Ziggy)->toArray();
if($request->host()!=config('app.admin_domain')) {
$ziggyObj['routes'] = array_filter(
$ziggyObj['routes'],
fn ($key) => !str_starts_with($key, 'admin'),
ARRAY_FILTER_USE_KEY
);
}
return array_merge(parent::share($request), [
'auth' => [
'user' => $request->user(),
],
'ziggy' => function () use ($ziggyObj, $request) {
return array_merge($ziggyObj, [
'location' => $request->url(),
]);
},
]);
}
So any routes that starts with "admin" are not sent to the frontend, unless it's the "admin domain".
The front-facing application routes are also sent to the backoffice, but I might filter those out later.

Related

How to write laravel 5.8 controllers routes similar to laravel 5.1

Having more than 20 controllers. It's very difficult to set each and every routes for add, edit and delete (also having more actions).
This is my laravel 5.1 routes.php :
Route::controllers([
'user' => 'UserController',
'taxes' => 'TaxController',
]);
Is there any way to support these routes in laravel 5.8?
You can use the Resource Controller and implement in routes/web.php. It will autogenerate the name for the route
//web.php
Route::resource('user', 'UserController');
Route::resource('taxes', 'TaxController');
Edit 1
If you want to exclude show method of the controller for the resource, You can add array inside the except method.
Route::resource('taxes', 'TaxController', [
'except' => ['show']
]);
Further, if you want to get only selected options, You can use only.
Route::resource('taxes', 'TaxController', [
'only' => ['index', 'create', 'store', 'edit']
]);
The controllers method was deprecated in Laravel 5.2. From the upgrade guide:
Implicit controller routes using Route::controller have been deprecated. Please use explicit route registration in your routes file.
1) Use Resource Routes
Provided that your controllers use the standard index, store, show etc methods you can simply use resource routes. For example:
Route::resource('user', 'UserController');
However if you want to exclude certain methods you can add them to the resource. For example:
Route::resource('user', 'UserController', ['except' => 'show']);
2) Declare Routes Explicitly
You can follow the Laravel 5.2 upgrade guide as above and instead declare each route explicitly.
3) Create a Macro
The Laravel router is Macroable. This means that you can add your own methods to it. For example, in your app service provider you could have the following:
Illuminate\Routing\Router::macro('controllers', function ($routes) {
// Create your own implementation of the controllers method.
});
This allows you to create your own implementation of the controllers method which means you wouldn't need to alter your routes or controllers, but you may need to dive in and look at Laravel's route handling to understand how to implement this.
I hope this helps.
You can use in the array, In as you call using routes. like {{route('claimsubmit')}}
Route::resource('claimform',array('as'=>'claimform','uses'=>'UserController#claimform');

How to make custom authentication on Laravel?

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.
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);
}

laravel middleware setting $request attribute, does it affect performance

In one of my middleware I have used something like this
$user = [
'name' => 'noob',
'phone' => '87548154'
]; /* which actually comes from redis cache */
$request->attributes->set('user', $user);
and in the controller i use it like
$request->get('user')['name']
OR
$request->get('user')['phone']
As this seems very flexible, I would like to attach more data into the $user array.
In the laravel docs its written above the get() method of Request class is
* Gets a "parameter" value from any bag.
* This method is mainly useful for libraries that want to provide some flexibility. If you don't need the
* flexibility in controllers, it is better to explicitly get request parameters from the appropriate
* public property instead (attributes, query, request).
* Order of precedence: PATH (routing placeholders or custom attributes), GET, BODY
My question is, is it going to be a good idea? because the most frequently used data is already attached in the middleware. So that I dont have to write extra codes in the controller methods again and again. Will it affect on performance for a high traffic server?
I personnally never work this way. You can access the current user from anywhere using the Auth facade as following :
\Auth::user()
It enable you to never send it when unnecessary and still use it from anywhere (controllers, models, blades or everything else).
Then to access your properties :
\Auth::user()->phone
and so on...

How does Laravel 5.4 Middleware work?

I've read manual of Laravel 5 but still don't find a solution for my problem.
My task: I need to run multiple websites on the one codebase.
What have I done for it? I made one main website and create table "sites" where I can add new satellites. It's all worked fine. But now, in front end part, I need to create middleware which will help me to divorce different parts of my engine.
I start to create middleware but I've only found 2 ways of middleware:
redirect to the correct URL
return $next($request) which means that this middleware will be always working.
I don't need a redirect. I just need one thing:
I need that in my web.php route file I can make routes with my middleware group:
For example:
Route::group(['middleware' => 'site'], function () {
//there will be only routes for my satellites
And
Route::group(['middleware' => 'web'], function () {
//There will be another routes which won't be on satellites
The problem is if I make a redirect on the main site my middleware still working and going into the cycle.
Is there any way to break middleware and don't going into the certain routes?
I've tried with HttpException but I've received only 404 or 500 errors, but I don't need it in this case.

Registering routes with Laravel but make them unaccessible

I am trying to make a single page CRUD application with Laravel. I will use ajax to create, edit and delete my entity, and also to render partial views. The corresponding controller methods will process the information and return the views.
I want to register the routes so I can call the different methods when necessary. I don't see any other way:
However, registering them so I can do something like this {{ Form::open(['route' => ['cities.store', $city->id]]) }} will allow access via the URL, and I only want to make those routes accessible through the tools I am going to create in that one page CRUD.
I can only think of applying a before filter, but what would be the filter? Also, any other ideas on how I should approach this situtation?
I've had to do something similar with a web service I created. Basically, I wanted only my app to be able to access the routes I created.
What I ended up doing was adding a hashed key to each request being sent, then checking for this key value in the controller. So, only if the key is present and matches the one sent would you then process the request.
Or, if you're using forms, you could do something like the following:
//check if request was sent from our form
if ( Session::token() !== Input::get( '_token' ) ) {
return Response::json( array(
'msg' => 'Unauthorized access attempt'
) );
}
Hope this helps.
another way that doesnt need tokens but is less secure, you got to know what you need,
is using laravels request information
if (Request::ajax())
{
//your action
}else{
//error
}
note this only works when your application always uses ajax you could even type this in your before filter and add it to all needed routes

Resources