Laravel Middleware Does not work in routes - php

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

Related

Laravel api route that grabs Auth::user() when Authorization is sent, but doesn't hit 401 whenever you don't

So right now I'm using Laravel's default auth for api routes by doing this:
Route::group(['middleware' => ['auth:api']], function() {
...
}
The only thing with this is that it will throw a 401 if a non logged in user hits that page.
What I'm wondering is if there's a way to have a route that will login the user if a token is sent, but if not, they can still hit the api.
I know this will most likely be a custom Middleware, but I don't have a lot of experience with creating Middlewares so I'm not really sure where to start
EDIT
app/Http/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 = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::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:1000,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Fruitcake\Cors\HandleCors::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'admin' => \App\Http\Middleware\IsAdmin::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'cors' => \Fruitcake\Cors\HandleCors::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}
Here's a pretty simplified version of my routes api.php file
routes/api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::group(['prefix' => 'v2', 'middleware' => ['cors:api']], function() {
//routes that people need to be logged into to do
Route::group(['middleware' => ['auth:api']], function() {
Route::post('/comments/save/{type}/{id}', 'App\Http\Controllers\Api\v2\CommentController#save');
Route::get('/leagues/{id}', 'App\Http\Controllers\Api\v2\LeaguesController#get');;
});
Route::post('/auth/login', 'App\Http\Controllers\Api\v2\AuthController#login');
Route::post('/contact', 'App\Http\Controllers\Api\v2\ContactController#sendMessage');
});
Basically I'm wanting the ability to hit the /leagues/{id} route with either a logged in user or a non logged in user. And if the user is logged in grab the user via Auth::user(). If it helps at all, I'm using React for a front end and sending an api_token in the Authorization header like Bearer $token.
I figured out a way by creating my own custom Middleware. For anyone interested, here it is:
<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
use App\Models\User;
class OptionalAuthenticate
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$header = $request->header('Authorization');
if(!empty($header)){
$token = str_replace('Bearer ', '', $header);
$user = User::where('api_token', '=', $token)->first();
if(!empty($user)){
Auth::login($user);
}
}
return $next($request);
}
}

laravel not setting session data from first time

Alright so I got this locale system with a middleware, the issue is that when I enter language "hu"it doesnt set it the first time, it usualy works only the 2nd time I do it...
web.php
Route::get('set_language/{locale}', function ($locale) {
Session::forget('my_locale');
session(['my_locale' => $locale]);
return Redirect::back();
});
Language.php inside HTTP/middleware
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Foundation\Application;
class Language {
public function __construct(Application $app, Request $request) {
$this->app = $app;
$this->request = $request;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$this->app->setLocale(session('my_locale', config('app.locale')));
return $next($request);
}
}
And of course I added it inside my Kernel.php on couple of spots that seemed correct
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 = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\Language::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,
\App\Http\Middleware\Language::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' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* #var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\Language::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
}
EDIT:
I forgot to mention, but in the config/app.php I've set it this way
'locale' => 'rs',
'locales' => ['rs', 'hu'],
'fallback_locale' => 'rs',
'available_locale' => ['rs', 'hu'],
So now If I got to the localhost:8000/set_language/rs it works, but if I do localhost:8000/set_language/hu it works only after I do it twice.
I tried dumping the session key my_locale and it stays as "rs" until I do the set_language/hu twice
So how I do it?
Go to: localhost:8000/set_language/hu
Go again to: localhost:8000/set_language/hu
Now it works...
Why isnt it being set the first time around?
Just to add up, if you are testing this, try setting your locale to RS first and then try to set it to HU

laravel session not persisting when view returned

I am building a laravel application where I have web and api routes.
I want to store sessions between my routes.
If i store as session without returning a view, it works fine.
But when i return a view my session no longer exists.
My web.php is as follows:
Route::get('/', 'ViewController#index');
Route::get('/check', 'ViewController#check');
My controller
public function index(Request $request)
{
$request->session()->put('test','123456');
$request->session()->save();
//echo $request->session()->get('test', 'default_value');
// return view('welcome'); //If I uncomment this the sessions are not working anymore.
}
public function check(Request $request)
{
echo $request->session()->get('test', 'default_value');
var_dump($request->session()->all());
//return view('welcome');
}
Maybe it has something to do that i also store sessions in my api routes in the api controllers. My api.php:
Route::group(['middleware' => ['web']], function () {
//board
Route::get('/board/create', 'BoardController#create');
Route::post('board/{id}/guess', 'BoardController#guessWord');
Route::get('/board/set', 'BoardController#set');
Route::get('/board/get', 'BoardController#get');
//user
Route::get('/user', 'UserController#get');
Route::post('/user/create', 'UserController#create');
});
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,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}
Thanks!
From the docs api routes does not use StartSession middleware because session is only available in web group of middlewares
So store session only in web routes

How can I authenticate a request using Laravel Passport having the access token in query string instead of in header?

Authentication works fine using 'middleware' => 'auth:api' on regular endpoints where the client sends the Authorization=Bearer <access_token>.
But now I'd like to handle plain image download requests, without Authorization header, having the access token in the query string like this: GET /picture/my_picture.png?access_token=1234.
I tried something like this in my middleware, but I can't seem to add headers to the Request:
if ($request->has('access_token')) {
// something like $request->header->set('Authorization', 'Bearer ' . $request->get('access_token'));
}
if ($this->auth->guard($guard)->guest()) {
// throw exception
}
Can this be done? Maybe intercept or override something/somewhere else?
I had similar issue
In your
App\Http\Kernal.php
register your middleware in
$middleware and
$routeMiddleware
<?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 = [
\App\Http\Middleware\AddHeaderAccessToken::class,
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::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 = [
'addAccessToken' => \App\Http\Middleware\AddHeaderAccessToken::class,
'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,
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class
];
}
Middleware
<?php
namespace App\Http\Middleware;
use Closure;
class AddHeaderAccessToken
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($request->has('access_token')) {
$request->headers->set('Authorization', 'Bearer ' . $request->get('access_token'));
}
return $next($request);
}
}

Validation is not work on laravel 5.2.32

I am using Laravel 5.2.32, the validation of it is not work. I have tried to find solution on google and stackoverflow. However, the solution which can fix the 5.2.20 to 5.2.26 cannot fix the problem of laravel 5.2.32. Who can help me?
I have changed the router in the web middleware, the code as the following:
Route::group(['middleware' => ['web']], function () {
Route::get('/', function () {
return view('app/welcome');
});
Route::post('/signup', 'UserController#postSignup');
Route::post('/signin', 'UserController#postSignin');
Route::get('/dashboard', 'UserController#getDashboard');
Route::get('/logout', 'UserController#getLogout');
});
I also change the Kernel.php as the following. But it's still not work.
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,
\app\Http\Middleware\VerifyCsrfToken::class,
];
The code in my controller as below:
namespace app\Http\Controllers;
use app\User;
use Illuminate\Http\Request;
use app\Http\Requests;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\Middleware\ErrorBinder;
use Validator;
class UserController extends Controller
{
// public function __construct()
// {
// $this->middleware('auth');
// }
public function postSignUp(Request $request)
{
$this->validate($request, [
'email' => 'required | email | unique:users',
'first_name' => 'required | max:60',
'password' => 'required | min:8'
]);
if ($request['password'] === $request['password_confirmation'])
{
$user = new User();
$user->first_name = $request['first_name'];
$user->email = $request['email'];
$user->password = bcrypt($request['password']);
$user->save();
Auth::login($user);
return view('app/dashboard');
}
// return redirect()->back();
}
}
you don't need the middleware web in your route anymore as its baked in to the latest version, s can do without the following:
Route::group(['middleware' => ['web']], function () {...
and your kernel something like...
/**
* 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,
],
'api' => [
'throttle:60,1',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];

Categories