I'm new with Laravel, and my web application consists of 3 types of users (guards): Admins, Agents, Players.
Authentication is working fine with Admins and Agents, since they shouldn't be able to see their dashboard unless they are logged in.
The problem with Players, which can access all the pages in the website as guests and when they login the only change is in the navigation bar.
I'm getting the following error:
Firefox has detected that the server is redirecting the request for this address in a way that will never complete.
RouteServiceProvider.php
public const HOME = '/';
public const LOGGEDIN = '/loggedin';
public const AGENT = '/agent';
public const ADMIN = '/admin';
web.php
Route::group(['namespace' => 'Front','middleware' => 'guest:player', 'middleware' => 'auth:player'], function(){
Route::get('/','FrontController#index')-> name('front.home');
Route::get('loggedin','FrontController#index')-> name('front.loggedin');
Route::get('Page1','FrontController#get_page1')-> name('front.page1');
Route::get('Page2','FrontController#get_page2')-> name('front.page2');
Route::get('logout','FrontController#logout')-> name('front.logout');
});
Authenticate.php
protected function redirectTo($request)
{
$current_req = request()->segment(count(request()->segments()));
if($current_req == 'admin'){
return route('admin.login');
}
elseif($current_req == 'agent'){
return route('agent.login');
}
elseif($current_req == ''){
return route('front.home');
}
else{
return route('front.home');
}
}}
RedirectIfAuthenticated.php
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
if($guard == 'agent')
return redirect(RouteServiceProvider::AGENT);
elseif($guard == 'admin')
return redirect(RouteServiceProvider::ADMIN);
elseif($guard == 'player'){
return redirect(RouteServiceProvider::LOGGEDIN);
}
else
return redirect(RouteServiceProvider::HOME);
}
return $next($request);
}
Related
I am stuck with users profile feature, I want only authenticated users to access their own profile only.
User with id: 1 can only access route /applicants/profile/1, otherwise return 404 Not found?
class ApplicantProfileController extends Controller
{
public function show(Applicant $applicant)
{
return view('applicant.show', compact('applicant'));
}
}
route::group(['prefix' => 'applicants', 'middleware' => 'auth:applicant'], function() {
Route::get('/profile/{applicant}', 'Profiles\ApplicantProfileController#show');
});
You can chech whether the logged user and the parameter user are the same by using the Illuminate/Support/Facades/Auth facade like this:
public function show(Applicant $applicant)
{
if (Auth::id() == $applicant->id) {
return view('applicant.show', compact('applicant'));
}
return abort(404);
}
I am trying to implement 3 user types in to my application, I am using the default Auth of Laravel.
I created 2 extra middlewares to acheive the to extra user(admin & Districtlogin) conditions along with user approval middleware, and using the default for laravel user
Admin middleware
class Admin
{
tion handle($request, Closure $next)
{
if( Auth::check() && Auth::user()->isAdmin == 1)
{
return $next($request);
}
Auth::logout();
return redirect('login')->with('error','You have not admin access');
}
}
Districtlogin Middleware
class Districtlogin
{
public function handle($request, Closure $next)
{
if (Auth::check() && Auth::user()->isAdmin == 2) {
return $next($request);
}
Auth::logout();
return redirect('login')->with('error', 'You have not admin access');
}
}
One additional middleware to check if the user is approved
class ApproveUser
{
public function handle($request, Closure $next)
{
if( Auth::check() && Auth::user()->row_status == 1)
{
return $next($request);
}
return redirect('/userapprove');
}
I am able to redirect them based on the login
Auth/LoginController
public function redirectPath()
{
if (Auth::user()->isAdmin == 1 && Auth::user()->row_status == 1) {
return '/adminindex';
} elseif (Auth::user()->row_status == 0) {
return '/userapprove';
} elseif (Auth::user()->isAdmin == 2 && Auth::user()->row_status == 1) {
return '/districtindex';
}
return '/engineerdashboard';
}
Here is my
kernel.php
entry
'admin' => \App\Http\Middleware\Admin::class,
'districtlogin' => \App\Http\Middleware\Districtlogin::class,
'userapprove' => \App\Http\Middleware\ApproveUser::class,
I would like to group the admin and Districtlogin middleware.
I am using CRUD, I would like Districtlogin to have access to few controllers - index,store,update
When I try to group the middleware, I am redirected back to the login screen. Neither of the middleware works
Here's what I tried,
1)
Route::middleware(['admin'])->group(function () {
//Admin Dashboard
Route::resource('adminindex', 'AdminindexController')->middleware('districtlogin');
Route::get('adminindex/new', 'AdminindexController#admindashboard');
});
2)
Route::middleware(['admin','districtlogin'])->group(function () {
//Admin Dashboard
Route::resource('adminindex', 'AdminindexController');
Route::get('adminindex/new', 'AdminindexController#admindashboard');
});
3)
Route::middleware(['admin',''])->group(function () {
//Admin Dashboard
Route::resource('adminindex', 'AdminindexController');
Route::get('adminindex/new', 'AdminindexController#admindashboard');
Route::middleware(['districtlogin'])->group(function () {
Route::resource('adminindex', 'AdminindexController');
});
});
But when I use the 'OR' condition, I am able to access the pages
Route::group(['middleware' => ['admin' OR 'districtlogin']], function () {
//Admin Dashboard
Route::resource('adminindex', 'AdminindexController');
Route::get('adminindex/new', 'AdminindexController#admindashboard');
});
The controllers are accessible by both the middlewares. But how do I limit the Crud functions based on the middleware.
I am completely clueless on how to achieve it.
The complete answer is:
The two middlewares are incompatible with each other, they have no common ground. Where one succeeds the other fails and redirects to login page.
So this explains the first part of your question.
The second part is that Route::group(['middleware' => ['admin' OR 'districtlogin']] .. is meaningless as regards to configuring middleware. it is equivalent to Route::group(['middleware' => ['admin']].. since the expression 'admin' OR 'districtlogin' always evaluates to first operand. Plus it is misleading as Laravel does not support having middlewares one or the other it is meaningless expression.
The solution:
Either use one middleware that can support both options, for example:
class AdminOrDistrictlogin
{
public function handle($request, Closure $next)
{
if (Auth::check() && Auth::user()->isAdmin >= 1 ) {
return $next($request);
}
Auth::logout();
return redirect('login')->with('error', 'You have not admin access');
}
}
entry:
'adminOrdistrict' => \App\Http\Middleware\AdminOrDistrictlogin::class,
'userapprove' => \App\Http\Middleware\ApproveUser::class,
routes:
Route::middleware(['adminOrdistrict'])->group(function () {
//Admin or District Dashboard, distignuish later in your code
Route::resource('adminindex', 'AdminindexController');
Route::get('adminindex/new', 'AdminindexController#admindashboard');
});
And in your controllers and views refine further by checking Auth::user()->isAdmin value for distinguishing between simple admins or districts
Or, if the functionality is very different between simple admins and districts, create new and different routes for admin and district and use each middleware in the appropriate route group for each type of user.
For example:
Route::middleware(['admin'])->group(function () {
//Admin Dashboard
Route::resource('adminindex', 'AdminindexController');
Route::get('adminindex/new', 'AdminindexController#admindashboard');
});
Route::middleware(['districtlogin'])->group(function () {
//District Dashboard
Route::resource('districtindex', 'DistrictindexController');
Route::get('districtindex/new', 'DistrictindexController#admindashboard');
});
Choice is yours :)
I'm using Laravel 5.5.
I created 4 middlewares, one middleware by user role.
The admin has same rights as the employee. However, admin owns some more privileges.
Routing File:
Route::group(['prefix' => 'admin'], function() {
// EMPLOYEE AND ADMIN ROUTES
Route::group(['middleware' => ['admin', 'employe']], function() {
Route::get('showCreationSeance', 'AdministrationController#showCreationSeance');
Route::get('showAjoutCoach', 'AdministrationController#showAjoutCoach');
Route::get('showReservationClient', 'AdministrationController#showReservationClient');
Route::get('showAnnulationClient', 'AdministrationController#showAnnulationClient');
Route::post('creerSeance', 'AdministrationController#creerSeance')->name('admin/creerSeance');
Route::post('ajouterCoach', 'AdministrationController#ajouterCoach')->name('admin/ajouterCoach');
});
// ADMIN ROUTES
Route::group(['middleware' => 'admin'], function() {
Route::get('showCreationActivite', 'AdministrationController#showCreationActivite');
Route::get('showAjoutEmploye', 'AdministrationController#showAjoutEmploye');
Route::post('creerActivite', 'AdministrationController#creerActivite')->name('admin/creerActivite');
Route::post('ajouterEmploye', 'AdministrationController#ajouterEmploye')->name('admin/ajouterEmploye');
});
});
Middlewares:
class AdminMiddleware
{
public function handle($request, Closure $next)
{
$user = User::getUser(Auth::user()->id_utilisateur);
if(!$user->estAdmin()) {
throw new AuthorizationException();
}
return $next($request);
}
}
class EmployeMiddleware
{
public function handle($request, Closure $next)
{
$user = User::getUser(Auth::user()->id_utilisateur);
if(!$user->estEmploye()) {
throw new AuthorizationException();
}
return $next($request);
}
}
Methods used into middlewares:
public function estAdmin() {
$idStatutAdmin = Statut::select('id_statut')
->where('nom_statut', '=', 'ROLE_ADMIN')
->first();
return ($idStatutAdmin->id_statut == $this->id_statut) ? true : false;
}
public function estEmploye() {
$idStatutEmployee = Statut::select('id_statut')
->where('nom_statut', '=', 'ROLE_EMPLOYEE')
->first();
return ($idStatutEmployee->id_statut == $this->id_statut) ? true : false;
}
Stack Trace:
Illuminate\Foundation\Exceptions\Handler render
…/app/Exceptions/Handler.php 51
Illuminate\Auth\Access\AuthorizationException
…/app/Http/Middleware/AdminMiddleware.php 25
Illuminate\Foundation\Http\Kernel handle
…/public/index.php 55
The problem:
The routes defined for admin and employee didn't work and I get an error:
Symfony \ Component \ HttpKernel \ Exception \ AccessDeniedHttpException
No message
While routes for admin only work perfectly. Can you tell me if I'm doing this correctly?
When I'm connected as an admin, it is EmployeMiddleware which throw an error. And when I'm connected as employee, it is AdminMiddleware which throw an error.
Thank's for your help!
The user has the id_statut column which can only be ROLE_ADMIN or ROLE_EMPLOYEE. Take the following example:
$roles = [
'admin' => 2,
'employee' => 1
];
$user = [
'id_statut' => 1
];
if ($user['id_statut'] == $roles['employee']) {
// User is an employee - this code will execute
}
if ($user['id_statut'] == $roles['admin']) {
// User is not an admin - this code will NOT execute
}
if ($user['id_statut'] == $roles['employee'] && $user['id_statut'] == $roles['employee']) {
// User is an employee AND an admin
// This is impossible based on your database structure as id_statut cannot be both 1 and 2
}
An easy solution would be to check if the user is an employee or higher permission in estEmploye(). For example:
public function estEmploye() {
$idStatutEmployee = Statut::select('id_statut')
->where('nom_statut', 'IN', ['ROLE_EMPLOYEE', 'ROLE_ADMIN'])
->get('id_statut');
return in_array($this->id_status, $idStatutEmployee);
}
I want to run the following code to check if the user is logged via social media and if so redirect him to the edit profile page, so he's obligated to update his information, I don't want the user logged via social media to be able to navigate my website without having their Name, username and profile resume set.
public function check_user_info()
{
$user = User::where('access_token', Auth::user()->access_token)->first();
if (empty($user->fname) || empty($user->lname) || is_null($user->username) || empty($user->username))
{
$user = Auth::user();
return view('modify')->with([
'user' => $user,
]);
}
return view('home');
}
You could create a user policy and add the following function :
public function home(User $user)
{
return (empty($user->fname) || empty($user->lname) || is_null($user->username) || empty($user->username));
}
and in you home controller :
public function index(){
try{
$this->authorize('home', User::class);
}catch(AuthorizationException $e){
return view('modify')->with([
'user' => Auth::user(),
]);
}
return view('home');
}
The user logs out after redirecting to the homepage after successful login. Even a before filter for auth fails on the route. I am using ollieread/multi-auth plugin.
Auth Controller
public function postLogin()
{
if (\Auth::biz()->attempt(\Input::only(array('email', 'password')), \Input::get('persist', 'no') == 'yes')) {
// dd(Auth::biz()->check()); returns true
return \Redirect::route('main.home');
} else {
return \Redirect::back()->withInput()->with('loginFail', true);
}
}
Route
Route::get('/{verify_token?}', array('as' => 'main.home', 'uses' => 'MainController#getIndex'));
Main Controller
public function getIndex($verify_token = '')
{
dd(\Auth::biz()->check()); // returns bool(false)
return \View::make('main.pages.home', array($emailVerified));
}