It's kinda strange because I followed everything that's online about getting route parameters in the middleware and all of them returns NULL or an error, That's what I already tried and didn't work:
public function handle($request, Closure $next)
{
$token = $request->access_token;
// Do something with $token
}
This one returns NULL.
public function handle($request, Closure $next)
{
$request->route('parameter_name');
// Do something with $token
}
And this one above reurns NULL.
public function handle($request, Closure $next)
{
$request->route()->parameters();
// Do something with $token
}
And this one above returns:
FatalThrowableError in CheckOwner.php line 22: Call to a member
function parameters() on null
What I want is to check if the current user trying to edit a product is the owner of this product based on two thing the id from the 'id' parameter of the URL and the 'user_id' in the products row in the database. and that's my code:
the middleware:
class CheckOwner
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
//Get product from $id to edit
$product = Product::find($request->parameter('product'));
if ($product->user_id != Auth::user()->id) {
return redirect('home');
}
return $next($request);
}
}
and that's my route which it's a resource route:
//Products controller show, store, edit, update, destroy
Route::resource('products', 'ProductsController');
and that's how I registered my middleware in the kernel page:
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\CheckOwner::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
/**** OTHER MIDDLEWARE ****/
'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class
// REDIRECTION MIDDLEWARE
];
}
Right now based on the code above it returns this error:
BadMethodCallException in Macroable.php line 74: Method parameter does
not exist.
UPDATE: That's where I use the middleware, in the constructor of the controller:
public function __construct()
{
//Kick him/her out if he is not logged in
$this->middleware('auth', ['except' => ['show']]);
$this->middleware('checkowner', ['except' => ['create', 'store', 'show', 'update', 'delete']]);
}
The global middleware run before the route is resolved.
If you need access to route parameters, use your middleware as route middleware:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\CheckOwner::class,
// the rest of your middleware...
],
];
Related
i have problem with laravel's (5.5) middlewares. Firstly, i created a middleware called AdminPanelAuth
Thats my middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
class AdminPanelAuth
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::user() && Auth::user()->hasRole('admin'))
{
return $next($request);
}
else{
return redirect()->route('home');
}
}
}
and registered to Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'admin' => \App\Http\Middleware\AdminPanelAuth::class,
'auth.basic' =>
\Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' =>
\Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' =>
\Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}
And i put that new admin middleware to my route file,
Route::group(
[
'namespace' => 'Backpack\Base\app\Http\Controllers',
'middleware' => ['web', 'admin'],
'prefix' => config('backpack.base.route_prefix'),
],
function () {
...
};
Admin middleware does not work for my routes. I've been tried to put this in web.php but nothings changed, still not working for me.
ps. i allready use composer dump-autoload, php artisan clear:compiled and php artisan optimize.
Thanks for your helps, best regards!
Try separating web middleware from admin like this:
Route::group(['middleware' => 'web', 'prefix' => config('backpack.base.route_prefix')], function () {
...
Route::group(['middleware' => 'admin'], function() {
...
});
...
};
EDIT:
In your middleware add use Illuminate\Support\Facades\Auth;
And in your Kernel, add admin middleware you created under throttle
EDIT 2:
Kernel.php
protected $middlewareGroups = [
'web' => [
...
\App\Http\Middleware\AdminPanelAuth::class, //Make sure your middleware is last in array
],
...
]
web.php
Route::group(['middleware' => 'web', 'prefix' => config('backpack.base.route_prefix')], function () {
...
};
I'm attempting to bind a function to the routing so it takes effect globally.
Basically I'm using Hashids to obfuscate the IDs, and want to be able to decode the ID on the route level so I don't need to do it everywhere the ID is uses in different controllers.
I've attempted to do the following at the top of the api routes file:
api.php
<?php
use Dingo\Api\Routing\Router;
use Hashids\Hashids;
Route::bind('id', function ($id) {
return Hasher::decode($id);
});
/** #var Router $api */
$api = app(Router::class);
But it doesn't seem to have any effect.
I have a couple of routes that use the ID I want to decode at the bottom of the routes file:
$api->get('leads/{id}', 'App\\Api\\V1\\Controllers\\LeadController#show');
$api->put('leads/update/{id}', 'App\\Api\\V1\\Controllers\\LeadController#update');
Really at a loss as to how to get this to work, I've tried using $api->bind and others but they all call undefined functions.
Sure this is an easy thing, but I'm just starting out with Laravel so this is a bit beyond me at this point.
Many thanks!
Based on the hint that Serge gave me, I've attempted to move this functionality into Middleware, but still due to a full lack of understanding, this isn't working.
I have the following middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use Junity\Hashids\Facades\Hashids;
class DecodeHashids
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if($request->has('id'))
$request->id = Hasher::decode($request->id);
return $next($request);
}
}
I've added it to Kernal.php:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
'decode',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'jwt.auth' => GetUserFromToken::class,
'jwt.refresh' => RefreshToken::class,
'decode' => \App\Http\Middleware\DecodeHashids::class,
];
}
and added it in the api routes file as so:
$api->group(['middleware' => 'jwt.auth'], function(Router $api) {
$api->get('protected', function() {
return response()->json([
'message' => 'Access to protected resources granted! You are seeing this text as you provided the token correctly.'
]);
});
$api->get('refresh', [
'middleware' => 'jwt.refresh',
function() {
return response()->json([
'message' => 'By accessing this endpoint, you can refresh your access token at each request. Check out this response headers!'
]);
}
]);
$api->group(['middleware' => 'decode'], function(Router $api) {
$api->get('leads/{id}', 'App\\Api\\V1\\Controllers\\LeadController#show');
});
I get no errors, but the ID is not decoded when it passes through to the controller.
Thanks to the help from Serge, I managed to complete the Middleware.
Middleware as below, it updates the Route ID Parameter with the decoded value, and this Middleware is added to the Kernal.
<?php
namespace App\Http\Middleware;
use Closure;
use Hashids;
class DecodeHashids
{
public function handle($request, Closure $next)
{
if($request->route()->parameters('id'))
$request->route()->setParameter('id', Hashids::decode($request->id));
return $next($request);
}
}
Then in the API route file, I added a new group that uses the 'decode' Middleware:
$api->group(['middleware' => 'decode'], function(Router $api) {
$api->get('leads/{id}', 'App\\Api\\V1\\Controllers\\LeadController#show');
});
Can then of course add as many routes to this group where parameters need decoded.
Thanks Serge and the Laravel community for the help and responses on here and other sites. Hopefully this will help others.
I know this may seem duplicated. I have already checked these threads:
https://laracasts.com/discuss/channels/laravel/authuser-returns-null-in-laravel-52
https://medium.com/#mshanak/laravel-5-token-based-authentication-ae258c12cfea#.8qeglhfnq
Auth::user() returns null in Laravel 5.2
Laravel : Auth::user() returns null
But I haven't found the solution to my problem
After successfully getting the access_token for a user using the credentials Auth::user() returns null within the controllers.
Here is my Kernel.php
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\LucaDegasperi\OAuth2Server\Middleware\OAuthExceptionHandlerMiddleware::class,
];
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'oauth' => \LucaDegasperi\OAuth2Server\Middleware\OAuthMiddleware::class,
'oauth-user' => \LucaDegasperi\OAuth2Server\Middleware\OAuthUserOwnerMiddleware::class,
'oauth-client' => \LucaDegasperi\OAuth2Server\Middleware\OAuthClientOwnerMiddleware::class,
'check-authorization-params' => \LucaDegasperi\OAuth2Server\Middleware\CheckAuthCodeRequestMiddleware::class,
'csrf' => \App\Http\Middleware\VerifyCsrfToken::class,
];
Here is my routes.php
Route::group(['prefix' => $api_prefix, 'middleware' => 'oauth', 'namespace' => 'Api'], function () {
Route::resource('user', 'UserController', ['except' => ['create', 'store']]);
Route::resource('post', 'PostController');
Route::post('follow/{user}', 'UserRelationsController#follow');
Route::post('unfollow/{user}', 'UserRelationsController#unfollow');
Route::post('trade/{user}', 'UserRelationsController#trade');
Route::post('untrade/{user}', 'UserRelationsController#untrade');
Route::post('capturetime', 'TimeCaptureController#store');
});
Any help would be appreciated
You need to use Authorizer::getResourceOwnerId() to get the user id. After that you should be able to use Auth::loginUsingId($userId) to log in the user for that request. You could set up a middleware to do this for you, would be something like this:
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$userId = Authorizer::getResourceOwnerId();
if($userId) {
Auth::loginUsingId($userId);
}
return $next($request);
}
in my Laravel 5.3 authentication, I'm using a middleware to verify if the user is logged in to access some page...
The problem I'm facing is that que middleware ALWAYS redirect to the login page, even when I just did log in...
My routes:
Route::get('/', 'ProdutoController#lista');
Route::get('/produtos', 'ProdutoController#lista');
Route::get('/produtos/mostra/{id}', 'ProdutoController#mostra');
Route::get('/produtos/novo', 'ProdutoController#novo');
Route::post('/produtos/adiciona', 'ProdutoController#adiciona');
Route::get('produtos/lista-json', 'ProdutoController#listaJSON');
Route::get('/produtos/remove/{id}', 'ProdutoController#remove');
Auth::routes();
Route::get('/home', 'HomeController#index');
Route::get('/login', 'LoginController#form');
Route::post('/login', 'LoginController#login');
My LoginController
class LoginController extends Controller
{
public function form () {
return view('form_login');
}
public function login () {
// Credenciais (email e senha)
$credenciais = Request::only('email', 'password');
// Login
if (Auth::attempt($credenciais)) { // caso as credenciais sejam aceitas, retorna true
return 'Usuário ' . Auth::user()->name . ' logado com sucesso';
}
else {
return 'Usuário não existe';
}
}
}
My ProdutoController
class ProdutoController extends Controller
{
public function __construct()
{
$this->middleware('Autorizador');
}
public function lista()
{
$produtos = Produto::all();
return view('produto/listagem')->with('produtos', $produtos);
}
}
My Kernel:
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\Autorizador::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}
My middleware:
class Autorizador
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next) // next é o código que será executado em seguida
{
if (!$request->is('login') && Auth::guest()) {
return redirect('/login');
}
return $next($request);
}
}
When I log in, I receive the message telling me that the log in was successfull and infoming me the name of the logged user, but then, when I try to access the list of my products, I am redirected to the login form again...
Any suggestions?
I would suggest you in your Kernel.php add your middleware in $routeMiddleware instead of $middleware as:
Kernel.php
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'autorizador' => \App\Http\Middleware\Autorizador::class,
];
}
And in your ProdutoController.php use it as:
public function __construct()
{
$this->middleware('autorizador');
}
I'm trying to add a simple middleware to check if a user matches a role. I'm running into an issue when I use the middleware, I get an Exception:
ReflectionException: class role does not exist
I do not attempt to call a class named role so I assume this is happening magically in Laravel somewhere.
My middleware:
class RoleMiddleware
{
/**
* Run the request filter.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string $role
* #return mixed
*/
public function handle($request, Closure $next, $role)
{
if (! $request->user()->is($role)) {
return redirect('/login');
}
return $next($request);
}
}
In the users table, I have a role field and in the User model I have:
/**
* Check if a user is a certain role
*
* #param $role
* #return bool
*/
function is($role) {
return ($this->role == $role);
}
The route group:
Route::group(['prefix' => 'support', 'middleware' => ['role:admin', 'web']], function() {
Route::get('threads', 'ThreadController#index');
});
In Http/Kernel.php:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
'role' => [
RoleMiddleware::class,
],
];
Anyone have any ideas on what could be causing this ReflectionException?
For Spatie/Laravel-Permissions to work properly we have to register the two route middleware (role and permission) in app/Http/Kernel.php as follows, along with the other two auth middleware:
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
];
In Http/Kernel.php, you need to include the full path to RoleMiddleware. E.g.:
...
'role' => [
\App\Http\Middleware\RoleMiddleware::class,
],
...
Try to change this
Route::group(['prefix' => 'support', 'middleware' => ['role:admin', 'web']], function() {
Route::get('threads', 'ThreadController#index');
});
to
Route::group(['prefix' => 'support', 'middlewareGroups' => ['role:admin', 'web']], function() {
Route::get('threads', 'ThreadController#index');
});
I'm a beginner in laravel i was facing this same problem and fixed by changing the name from middleware to "your-own-middelware-name".
This came down to two problems:
$middlewareGroups may not allow for parameters. (Needs to be confirmed) Dropping RoleMiddleware down to $routeMiddleware got rid of the exception.
Having 'web' after 'role:admin' resulted in a null $request->user(). So for future users, you may need to consider placement of your middleware and a check to see if $request->user() is null.
Hope this helps someone else.