Same route url use to multiple middlewares in laravel - php

I have two two middlewares. One is admin and another is teacher. In admin, will access all the created url and teacher will get only 2 or 3 url.
Here is my route
Route::group(['middleware' => ['adminAuth']], function () {
Route::get('dashboard', array('as' =>'Teacher Dashboard', 'uses' => 'UserController#dashBoard'));
Route::get('users/profile/edit/{id}', array('as' => 'User Profile Update', 'uses' => 'UserController#userProfile'));
Route::post('users/profile/update/{id}', array('as' => 'User Profile Update', 'uses' => 'UserController#updateUserProfile'));
Route::get('student/leave/application', array('as' => 'Student Leave Application', 'uses' =>'LeaveApplicationController#studentLeaveApplicationList'));
Route::get('leave/application/student/create', array('as' => 'Student Leave Application', 'uses' =>'LeaveApplicationController#studentLeaveApplicationCreate'));
Route::post('leave/student/application/store', array('as' => 'Student Leave Application', 'uses' =>'LeaveApplicationController#studentLeaveApplicationStore'));
Route::get('leave/student/application/categories', array('as' => 'Student Leave Application Categories', 'uses' => 'LeaveApplicationController#studentLeaveCategories'));
});
Route::group(['middleware' => ['teacherAuth']], function () {
Route::get('teacher/dashboard', array('as' =>'Teacher Dashboard', 'uses' => 'UserController#teacherDashBoard'));
Route::get('users/profile/edit/{id}', array('as' => 'User Profile Update', 'uses' => 'UserController#userProfile'));
Route::post('users/profile/update/{id}', array('as' => 'User Profile Update', 'uses' => 'UserController#updateUserProfile'));
});
I want to update each user profile from both middleware. it is working fine when i use profile update url for anyone middleware but when i use profile update url in both middleware then it not wokring just redirect to another url
Here is my middlewares logic
For Admin,Middleware/AdminAuth.php
public function handle($request, Closure $next)
{
$role = User::getUserById(Auth::id());
if(!(\Auth::check()) || ($role->role_name != "admin"))
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
} else {
\Session::flash('errormessage','Invalid Request');
\Session::put('pre_login_url',\URL::current());
return redirect()->guest('/auth/login');
}
}
return $next($request);
}
For Teacher, Middleware/TeacherAuth.php
public function handle($request, Closure $next)
{
$role = User::getUserById(Auth::id());
if(!(\Auth::check()) || ($role->role_name != "teacher"))
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
} else {
\Session::flash('errormessage','Invalid Request');
\Session::put('pre_login_url',\URL::current());
return redirect()->guest('/auth/login');
}
}
return $next($request);
}
Here is my Kernel.php
'adminAuth'=>\App\Http\Middleware\AdminAuth::class,
'teacherAuth'=>\App\Http\Middleware\TeacherAuth::class,

Laravel uses pattern matching for routes and it settles for the first one found. Middlewares don't change route paths so laravel will only recognise the first users/profile/update/{id} route.
You either change the route path so they're not exactly the same, or you go and separate the logic in your controller method. For example, in your UserController::updateUserProfile() method, you can create private methods updateTeacher(), updateAdmin(). So your logic can look like this:
if($role->role_name == "teacher")
{
return $this->updateTeacher();
} else if($role->role_name == "admin")
{
return $this->updateAdmin();
}
Which means you won't need those 2 middlewares. Just apply auth middleware on the route

Related

Laravel Route Middleware auth:admin not working for all Routes

I'd like to pre check two different Route Groups by the auth:admin middleware. This works perfectly for the first Route Group inside but not for the second which is in an other Namespace.
My Routes file looks like this:
Route::group(['middleware' => ['auth:admin']], function(){
Route::group(['prefix' => 'admin', 'namespace' => 'Admin', 'as' => 'admin.'], function(){
Route::resource('dashboard', 'DashboardController')->only(['index', 'create', 'store']);
});
Route::group(['prefix' => 'team/{team_id}', 'namespace' => 'Team', 'as' => 'team.'], function(){
Route::resource('dashboard', 'DashboardController')->only(['index', 'create', 'store']);
});
});
If I'm not logged in and try to go to admin/dashboard, I'm redirected to login/admin. But if I try to go to team/1/dashboard it says Error 'Trying to get property 'headers' of non-object'.
How can I get the auth:admin Middleware to work with my Team Routes too?
create a middleware
class IsAdmin
{
public function handle($request, Closure $next)
{
if (Auth::user()->permission == 'admin') {
return $next($request);
}
return redirect()->route('some.route'); // If user is not an admin.
}
}
Register in kernel.php
protected $routeMiddleware = [
....
'is.admin' => \App\Http\Middleware\IsAdmin::class,
];
So your routes:
Route::group(['middleware' => 'is.admin'], function () {
Route::group(['prefix' => 'admin', 'namespace' => 'Admin', 'as' => 'admin.'], function(){
Route::resource('dashboard', 'DashboardController')->only(['index', 'create', 'store']);
});
Route::group(['prefix' => 'team/{team_id}', 'namespace' => 'Team', 'as' => 'team.'], function(){
Route::resource('dashboard', 'DashboardController')->only(['index', 'create', 'store']);
});
});
check app/Http/Controllers/Middleware/RedirectIfAuthenticated.php file and
update the code for different guard use
// app/Http/Controllers/Middleware/RedirectIfAuthenticated.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
public function handle($request, Closure $next, $guard = null)
{
if ($guard == "admin" && Auth::guard($guard)->check()) {
return redirect('/admin');
}
if ($guard == "writer" && Auth::guard($guard)->check()) {
return redirect('/writer');
}
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}

Laravel Route [dashboard] is not defined

Trying to play with Laravel today for the first time. I am getting the following error when I attempt to visit:
InvalidArgumentException
Route [dashboard] not defined.
routes/web.php
Route::get('/', ['as' => '/', 'uses' => 'LoginController#getLogin']);
Route::post('/login', ['as' => 'login', 'uses' => 'LoginController#postLogin']);
Route::get('/logout', ['as' => 'logout', 'uses' => 'LoginController#getLogout']);
Route::group(['middleware' => ['authenticate', 'roles']], function (){
Route::get('/dashboard', ['as' => 'dashboard', 'uses' => 'DashboardController#dashboard']);
});
LoginController.php
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $username = 'username';
protected $redirectTo = '/';
protected $guard = 'web';
public function getLogin()
{
if (Auth::guard('web'))
{
return redirect()->route('dashboard');
}
return view('login');
}
public function postLogin(Request $request)
{
$auth = Auth::guard('web')->attempt([
'username' => $request->username,
'password' => $request->password,
'active' => 1]);
if ($auth)
{
return redirect()->route('dashboard');
}
return redirect()->route('/');
}
public function getLogout()
{
Auth::guard('web')->logout();
return redirect()->route('/');
}
}
as like name(). You should use one of the two :
Route::group(['middleware' => ['authenticate', 'roles']], function (){
Route::get('/dashboard', 'DashboardController#dashboard')->name('dashboard');
});
Or
Route::group(['middleware' => ['authenticate', 'roles']], function (){
Route::get('/dashboard', [
'as' => 'dashboard',
'uses' => 'DashboardController#dashboard']);
});
After, you clear route cache with php artisan route:clear
Final, you can use php artisan route:list to lists all routes and the action bind
Try this:
Route::get('/dashboard','DashboardController#dashboard')->name('dashboard');
When you use as it names the route , so you have add two name dashbbaorddashboard because you use as and name
Route::group(['middleware' => ['authenticate', 'roles']], function (){
Route::get('/dashboard', ['uses' => 'DashboardController#dashboard'])->name('dashboard');
});
This will work

Laravel 5.2 login with external validation does not persist

to login I'm using laravel with an external validation of user credentials, after redirection data stored in Auth::user() doesn't persist and Auth::check() = false, but the session data saved correctly. After the login if I enter to the dashboard I 'm redirected to the login.
Routes.php
Route::group(['middleware' => ['web']], function () {
Route::get('/test', [
'as' => 'test',
function () {
echo "Session------>";
var_dump(\Illuminate\Support\Facades\Session::get('user'));//Returns user data
echo "User------>";
var_dump(\Illuminate\Support\Facades\Auth::user());// Returns null
echo "\ncheck user.------->";
var_dump(\Illuminate\Support\Facades\Auth::check());//Returns false
}
]);
});
//Login
Route::group(['middleware' =>[ 'web']], function () {
Route::get('/login', ['as' => 'login', 'uses' => 'AuthController#login']);
Route::post('/login', ['as' => 'login', 'uses' => 'AuthController#loginpost']);
Route::get('/logout', ['as' => 'logout', 'uses' => 'AuthController#logout']);
});
Route::group(['middleware' => ['auth', 'web']], function () {
Route::get('/', ['as' => 'home', 'uses' => 'DashboardController#index']);
//Dashboard
Route::get("/dashboard", ['as' => 'dashboard', 'uses' => 'DashboardController#index']);
}
AuthController.php
class AuthController extends Controller
{
public function login()
{
return view('auth/login');
}
public function loginpost(LoginRequest $request)
{
$credentials = $request->only('username', 'password');
$loginRequest = new LoginUserRequest($credentials['username'], md5($credentials['password']));
$userRepo = new MongoUserRepository();
$service = new GetUserByCredentialsService($userRepo, $loginRequest);
$authUser = $service->handle(new UserObjectPresenter());
var_dump($authUser);
if (isset($authUser)) {
$us = new User();
$us->id = $authUser->id;
$us->email = $authUser->email;
$us->fullname = $authUser->fullname;
Auth::login($us);
$user = Auth::user();
Session::put('user', $user);
Session::save();
echo "----saved user------";
var_dump(Auth::user()); //Returns correct user data
echo "Auth::check()->";
var_dump(Auth::check()); //Returns true
return redirect()->route('test');
} else {
return redirect()->route('login')->withInput()->withErrors(['Invalid email or password.']);
}
}
}
$service->handle(new UserObjectPresenter()); returns null or user data if login is correct.
Use Auth::attempt after login we you actually starting your session, otherwise Auth::check always returns false,
use following code
$userdata = array(
'email' => Input::get('email'),
'password' => Input::get('password')
);
if (Auth::attempt($userdata)) {
return view('dashboard');
}
You aren't passing an 'existing' user record to Auth::login. It has no id so it won't be able to be pulled back up on the next request.
Save that user record or use an existing one to pass to Auth::login

Launch 503 status for all routes with laravel routes.php file

I want launch a status code 503 for all my routes in Laravel 5.2.
I can not use the command 'php artisan down'.
So I want to do it manually in my file routes.php.
I try with this, but not working:
Route::any('/',function(){#this code not work for me
dd('not arrive here');
return abort(503);
});
This is the complete route.php file:
<?php
Route::any('/',function(){#this code not work for me
dd('not arrive here');
return abort(503);
});
// extra langs
$conf = Config::get('app.current_site_config');
$langs = [];
$langs[] = $conf['lng_default'];
if (!empty($conf['lng_extra']))
$langs = array_merge($conf['lng_extra'],$langs);
$prefix = false;
if (count($langs) > 1)
$prefix = true;
$pages = Config::get('app.web_config.lang_url');
foreach($langs as $lang)
{
foreach($pages as $key=>$value)
{
$key_underscored = str_replace('-','_',$key);
if ($prefix == false)
{
//echo $key_underscored.'_'.$lang.'<br>';
Route::any('/'.$value[$lang],['as' => $key_underscored.'_'.$lang, 'uses' => 'WebController#'.$key_underscored ]);
Route::get('/'.$value[$lang].'/{seo_name}/{id}',['as' =>$key_underscored.'_seo_'.$lang, 'uses' => 'WebController#'.$key_underscored]);
Route::get('/404-error', ['as' => 'error404'.'_'.$lang, 'uses' => 'WebController#error404']);
Route::get('/500-error', ['as' => 'error500'.'_'.$lang, 'uses' => 'WebController#error500']);
Route::post('shipping-info-post', ['as' => 'shipping_info_post'.'_'.$lang, 'uses' => 'WebController#shipping_info_post']);
Route::post('payment-post', ['as' => 'payment_post'.'_'.$lang, 'uses' => 'WebController#payment_post']);
Route::post('cart-post', ['as' => 'cart_post'.'_'.$lang, 'uses' => 'WebController#cart_post']);
}
else
{
//echo '/'.$lang.'/'.$value[$lang] . ' as '.$key_underscored.'_'.$lang.' uses '. 'WebController#'.$key_underscored.'<br>';
Route::any('/'.$lang.'/'.$value[$lang],['as' => $key_underscored.'_'.$lang, 'uses' => 'WebController#'.$key_underscored]);
Route::get('/'.$lang.'/'.$value[$lang].'/{seo_name}/{id}',['as' =>$key_underscored.'_seo_'.$lang, 'uses' => 'WebController#'.$key_underscored]);
// generic (not optimized for SEO)
Route::get('/'.$lang.'/404-error', ['as' => 'error404_'.$lang, 'uses' => 'WebController#error404']);
Route::get('/'.$lang.'/500-error', ['as' => 'error500_'.$lang, 'uses' => 'WebController#error500']);
Route::post('/'.$lang.'/shipping-info-post', ['as' => 'shipping_info_post_'.$lang, 'uses' => 'WebController#shipping_info_post']);
Route::post('/'.$lang.'/payment-post', ['as' => 'payment_post_'.$lang, 'uses' => 'WebController#payment_post']);
Route::post('/'.$lang.'/cart-post', ['as' => 'cart_post_'.$lang, 'uses' => 'WebController#cart_post']);
}
}
}
if (count($langs) > 1)
{
Route::get('/',function(){
header('Location: '.route('index_'.Config::get('app.locale')).'/');
exit;
});
}
else
Route::get('/', ['as' => 'index_'.$langs[0], 'uses' => 'WebController#index']);
How I can launch the 503 state above all routes of my site?
Just add an empty file called down in the following folder and you're good to go : /storage/framework/.
That's basically what's php artisan down does in /vendor/laravel/framework/src/Illuminate/Foundation/Console/DownCommand.php :)
public function handle($request, Closure $next)
{
return response()->view('503',[], 500);
}
we must create 503.blade.php page in view directory to handle request.
Create a middleware that return a 503 and apply it as a group to your routes.

Laravel 5 route same urls login or not

I am updating a site from Laravel 4 to 5. In L4 I had this set up:
if(Sentry::check()){
Route::get('/', array('as' => 'school.home.index', 'uses' => 'school\AuthSchoolController#index'));
else{
Route::get('/', 'school\SchoolController#index');
}
Note the same url but different controllers depending on login or not.
With L5 I cannot use the middleware tried this:
Route::get('/', 'SchoolController#index');
Route::group(['middleware' => 'auth'], function()
{
Route::get('/', array('as' => 'school.home.index', 'uses' => 'AuthSchoolController#index'));
});
But this just passes over the first and goes to the group, where it gets redirected to the login page and to the admin if logged in.
So I think I need an if/else equivalent in the route based on login but Auth::user() for doesn't seem to work:
if(Auth::check()){
Route::get('/', array('as' => 'school.home.index', 'uses' => 'AuthSchoolController#index'));
}
else{
Route::get('/', 'SchoolController#index');
}
Route::get('/', function()
{
if( Auth::check() ) {
return app()->make('App\Http\Controllers\SchoolController')->callAction('index', []);
} else {
return app()->make('App\Http\Controllers\AuthSchoolController')->callAction('index', []);
}
});
Try reordering the routes like so:
Route::group(['middleware' => 'auth'], function()
{
Route::get('/', array('as' => 'school.home.index', 'uses' => 'AuthSchoolController#index'));
});
Route::get('/', 'SchoolController#index');

Categories