I have read almost everything in web and documentation but i can't find solution for my Problem.
I have a variable stored in Session , then I want to put this variable in every url generated by route('some-route') .
In Session I have sub = "mysubid"
When I generate Route route('my-route') I want to pass this sub parameter in query string: http://domain.dom/my-route-parameter?sub=mysubid
Can you help me to solve This problem? Any helpful answer will be appreciated;
You can use the Default Values feature.
First create a new middleware php artisan make:middleware SetSubIdFromSession. Then do the following:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\URL;
class SetSubIdFromSession
{
public function handle($request, Closure $next)
{
URL::defaults(['sub' => \Session::get('sub')]);
return $next($request);
}
}
At the end register your new middleware in app/Http/Kernel.php by adding it to $routeMiddleware.
protected $routeMiddleware = [
// other Middlewares
'sessionDefaultValue' => App\Http\Middleware\SetSubIdFromSession::class,
];
Add {sub} and the middleware to your route definition:
Route::get('/{sub}/path', function () {
//
})
->name('my-route')
->middleware('sessionDefaultValue');
Since you want this on every web route you can also add the middleware to the web middleware group:
protected $middlewareGroups = [
'web' => [
// other Middlewares
'sessionDefaultValue',
],
'api' => [
//
]
];
Try this , You need to create middleware php artisan make:middleware SetSubSession
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\URL;
class SetSubsSession
{
public function handle($request, Closure $next)
{
if(session('sub')){
$url = url()->full();
return redirect($url.'?sub='.session('sub'));
}
return $next($request);
}
}
in app/http/Kernel.php
protected $routeMiddleware = [
........
'setsubsession' => \App\Http\Middleware\SetSubsSession::class,
]
in route.php add
Route::group(['middleware' => 'setsubsession'], function(){
//and define all the route you want to add sub parameter
});
using this you don't need to change all your routes.This will automatic add "sub" in the route define in that middleware.
Related
I created a custom middleware to redirect short urls to other urls, I have a Url model that has this information:
{
"id":1,
"original_url":"http://www.google.com",
"short_url":"http://127.0.0.1:8000/wGjxw",
"updated_at":"2023-02-08T21:05:39.000000Z",
"created_at":"2023-02-08T21:05:39.000000Z"
}
so I have created a middleware:
<?php
namespace App\Http\Middleware;
use App\Models\Url;
use Closure;
use Illuminate\Http\Request;
class RedirectMiddleware
{
public function handle(Request $request, Closure $next)
{
//dd('here'); // is not reaching this code
$url = Url::where('short_url', $request->fullUrl())->first();
if ($url) {
return response()->redirectTo($url->original_url);
}
return $next($request);
}
}
app/Http/Kernel.php
....
....
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\RedirectMiddleware::class,
...
...
But, when I hit the url http://127.0.0.1:8000/wGjxw I get a 404 error,
This is the web.php
Route::get('/', function () {
return view('main');
});
Route::post('/urls', [UrlsController::class, 'store'] );
These routes are for showing the page with the form, and for creating the short url and those are working properly, the problem is that it looks like the middleware is not registered or I don't know what is happening, what I want is the short_url gets redirected to the original_url, what can I do? thanks
If the middleware approach isn't working, you could make a route specifically for it using route model binding with short_url as the key.
https://laravel.com/docs/9.x/routing#customizing-the-key
Route::get('/{url:short_url}', fn (Url $url) => redirect()->away($url->original_url));
My error was that the middleware was in the $middlewareGroups property, and it should be in the $middleware property, now it is working properly
I am using https://github.com/HipsterJazzbo/Landlord single database multi-tenancy solution for Laravel 5.2+. I have a companies table, and all other tables have a company_id column.
I'm not sure how to implement the call Landlord::addTenant($tenantColumn, $tenantId) in a global Middleware, in an auth system or in the constructor of a base controller... I'm confused...
How do I do that?
Is the parameter $tenantColumn equivalent to the company_id column of each of the tables?
Is the parameter $tenantId refers to the id of each company contained in the column company_id?
thank you!
A global middleware is not the good place because you don't have access to the authenticated user. A solution is to create a route middleware, for example:
<?php
namespace App\Http\Middleware;
use Closure;
use HipsterJazzbo\Landlord\Facades\Landlord;
use Illuminate\Support\Facades\Auth;
class LimitToCurrentCompany
{
public function handle($request, Closure $next)
{
if (Auth::check()) {
$tenant = Auth::user()->currentCompany;
Landlord::addTenant($tenant);
}
return $next($request);
}
}
add it to $routeMiddleware array in app/Http/Kernel.php:
protected $routeMiddleware = [
[…]
'limitToCurrentCompany' => \App\Http\Middleware\LimitToCurrentCompany::class,
];
Then in your routes file:
Route::group(['middleware' => 'limitToCurrentCompany'], function () {
// your routes
});
And yes, like said in the comment, $tenantColumn is the company_id and $tenantId is the id of the company.
I've implemented the cashier / billing feature from Laravel 5 and I'm trying to protect a group of routes using middleware which checks for a subscription.
I'm getting the following error:
Argument 2 passed to App\Http\Middleware\HasSubscription::handle() must be an instance of App\Http\Middleware\Closure, instance of Closure given
Heres my Middleware
<?php
namespace App\Http\Middleware;
class HasSubscription
{
public function handle($request, Closure $next)
{
if ($request->user() && ! $request->user()->subscribed()) {
// This user is not a paying customer...
return redirect('subscription');
}
return $next($request);
}
}
Heres my protected route
Route::get('home', 'PagesController#index')->middleware('subscription');
Heres my applications route declaration
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'subscription' => \App\Http\Middleware\HasSubscription::class,
];
Any idea why I get the error at the top?
Just add
use Closure;
to the top of your middleware, just before class definition:
namespace App\Http\Middleware;
use Closure;
class HasSubscription
{
...
Take a look on the the example in manual: http://laravel.com/docs/5.1/middleware#defining-middleware
I have many controllers and I want to set this code in the all of this(actually all of project), how can i do that?
if( !empty(Input::get('lan')) ){
Auth::user()->language = Input::get('lan');
App::setLocale( Auth::user()->language );
}else{
App::setLocale( Auth::user()->language );
}
You can use Laravel's middleware for that. Middleware is a layer of code that wraps the request processing and can execute additional code before or/and after request is processed.
First, you need your middleware class. It needs to have one method called handle() that will do the desired logic. In your case it could look like that:
<?php namespace App\Http\Middleware;
use Auth;
use App;
class SetLang {
public function handle($request, Closure $next) {
if(empty($request->has('lan'))) {
if (Auth::user()) {
Auth::user()->language = $request->input('lan');
Auth::user()->save(); // this will do database UPDATE only when language was changed
}
App::setLocale($request->input('lan'));
} else if (Auth::user()) {
App::setLocale(Auth::user()->language);
}
return $next($request);
}
}
Then register the middleware in your App\Http\Kernel class so that it gets executed for every request:
protected $middleware = [
//here go the other middleware classes
'App\Http\Middleware\SetLang',
];
You can find more info about Middleware in the docs here: http://laravel.com/docs/master/middleware
Seems that with newest versions of Laravel (im on 5.8) for this middleware to work you need to place it under $middlewareGroups otherwise the call to Auth::user() its always empty.
Following jedrzej-kurylo answer, just move the middleware to:
protected $middlewareGroups = [
'web' => [
...
'App\Http\Middleware\SetLang',
],
];
I follow this tutorial : https://www.youtube.com/watch?v=kmJYVhG6UzM Currently I can check in my blade if user is a admin or not like this:
{{ Auth::user()->roles->toArray()[0]['role'] }}
HI ADMIN
#endif
How can I make my route only available for admin user?
You need to create a middleware for your route.
Use: php artisan make:middleware AdminMiddleware.
You will find in your middleware folder a new file with this name.
Put your logic in your middleware, e.g.
public function handle($request, Closure $next)
{
if(Auth::check())
{
return $next($request);
}
else
{
return view('auth.login')->withErrors('You are not logged in');
}
}
Once you have done your logic in your middleware, you can either call it in the route or make the middleware apply to all routes.
If you want to add it to all routes, go to Kernel.php and add it to the $middleware array, e.g.
protected $middleware = [
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
'App\Http\Middleware\VerifyCsrfToken',
'App\Http\Middleware\AdminMiddleware',
];
If you want to add it to specific routes only, add it to the $routeMiddleware variable and add the alias to the route. E.g.
protected $routeMiddleware = [
'auth' => 'App\Http\Middleware\Authenticate',
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
'admin' => 'App\Http\Middleware\AdminMiddleware',
];
You can then add it to a route, as a filter, e.g.
Route::get('admin/profile', ['middleware' => 'admin', function()
{
}]);
For additional info visit the docs:
http://laravel.com/docs/master/middleware
EDIT
An improvement on this would be to use variadic functions which was introduced in PHP 5.6
http://php.net/manual/en/migration56.new-features.php
Instead of having to make a middleware for each permission set you can do the following
PermissionMiddleware
namespace App\Http\Middleware;
use Closure;
use \App\Models\Role;
class PermissionMiddleware
{
// Pass parameters to this middleware
public function handle($request, Closure $next, ...$permitted_roles)
{
//Get a users role
$role = new Role;
$role_name = $role->getUserRoleByName();
foreach($permitted_roles as $permitted_role) {
if($permitted_role == $role_name) {
return $next($request);
}
}
return redirect()->back()->withErrors('You do not have the required permission');
}
}
Notice the ...$permitted_roles
Route::get('admin/profile', ['middleware' => 'PermissionMiddleware:Admin,Marketing', function()
{
}]);
You can now specify as many roles as required for one middleware rather than creating multiple by using middleware parameters
Docs
https://laravel.com/docs/5.3/middleware#middleware-parameters
Let's assume you have a column in your users table with isAdmin name which has a default value of 0 (false)
You can give special access using middleware in laravel like you give access to logged in users using auth middleware in laravel.
Now you need to create a middleware using the command :
php artisan make:middleware AdminMiddleware
In your Kernel.php you need to add this line to protected $routeMiddleware
'admin' => \App\Http\Middleware\AdminMiddleware::class,
In your middleware folder you have the AdminMiddleware file.
In that you need to put your logic
In this case this is how it might look like depending upon you
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RoleMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::user()->isAdmin == '1') // is an admin
{
return $next($request); // pass the admin
}
return redirect('/'); // not admin. redirect whereever you like
}
}
Now in your route you have to pass the url using this middleware
Here is how it might look like
Route::get('/iamanadmin', ['middleware' => 'admin', function() {
return view('iamanadmin');
}]);
use middleware and check for admin user.
Route::get('admin', ['middleware' => 'checkadmin', function()
{
}]);
now create middleware and validate admin user.