Role-based routing in LoginController (Auth) - laravel

In my Laravel 5.3 setup, I am using Bouncer package, and I defined two roles, admin and customer. When logged in, customers are redirected to /home, as specified in protected $redirectTo = '/home'; under App\Http\Controllers\Auth\LoginController.php. Now, if a user with the role of an admin logs in, he is also redirected to /home because $redirectTo does not make any distinction between user roles. My goal here is to redirect admin users to /admin/home instead.
What is the best solution to handle this? Here is my attempt.
In web.php routes, outside of any middleware groups:
Route::get('/home', function(Illuminate\Http\Request $request) { // http://myapp.dev/home
if (Auth::user()->isA('customer')) // -> goto HomeController#index
return app()->make('\App\Http\Controllers\HomeController')->index($request);
else if (Auth::user()->isAn('admin')) // -> redirect
return redirect('/admin/home');
else
abort(403);
})->middleware('auth');
Route::group(['prefix' => 'admin','middleware' => 'auth'], function () {
Route::get('/home', 'Admin\HomeController#index');
});
Alternatively, this can can be done in a middleware, as well:
Route::get('/home', 'HomeController#index')->middleware('auth', 'role');
// in VerifyRole.php middleware...
public function handle($request, Closure $next, $guard = null)
{
if (Auth::user()->isAn('admin')) {
return redirect('/admin/home');
}
return $next($request);
}
This would work, but it's not scalable if more roles are added. I am sure there must be an elegant built-in way to accomplish this. So the question is, how do I route users to their proper dashboard (i.e. home) based on their role?

You can override the authenticated() method in your class App\Http\Controllers\Auth\LoginController as:
protected function authenticated(Request $request, $user)
{
if ($user->isA('customer'))
return redirect('/home');
else if ($user->isAn('admin'))
return redirect('/admin/home');
}
Or
You can override the redirectPath() method as:
public function redirectPath()
{
if (auth()->user()->isA('customer'))
return '/home';
else if (auth()->user()->isAn('admin'))
return '/admin/home';
}

In Laravel 5.3, you can override sendLoginResponse() method in AuthController.php to be able to redirect users to a different routes after login.

Related

laravel Localization per user

How do I change the language of each user? For example, some people don't change the language. Some people change the language.
Middleware :
use Closure;
use Auth;
class Localization
{
public function handle($request, Closure $next)
{
if(\Session::has('locale')) {
\App::setLocale(\Session::get('locale'));
}
return $next($request);
}
}
Save the locale for each user in database. This way you can override app's default locale to user's preferred locale in the middleware.
public function handle($request, Closure $next)
{
if($user = Auth::user()) {
App::setLocale($user->locale);
}
return $next($request);
}
If the your application doesn't require user to be authenticated, you can save locale in session for each user when the user change language.
Your method is right, no need to change the middleware. You can put the session on user with controller, like this below way.
Route :
Route::get('/lang',[
'uses' => 'HomeController#lang',
'as' => 'lang.index'
]);
Controller :
public function lang(Request $request)
{
$user = Auth::user()->id;
$locale = $request->language;
App::setLocale($locale);
session()->put('locale', $locale);
// if you want to save the locale on your user table, you can do it here
return redirect()->back();
}
Note : I added the GET method on route, so your URI will be like http://127.0.0.1:8000/lang?language=en, and o controller $request->language will catch the language parameter from your Request. You can modify and use POST method instead

Laravel: Redirect login & register if logged in?

I'm struggling to get the login/register pages to redirect the user if already logged in.
in routes.php
Route::group(array('before' => 'auth'), function()
{
Route::get('hud', 'HomeController#index')->name('hud');
Route::get('search', 'HomeController#search')->name('search');
Route::get('profile', 'UsersController#index')->name('profile');
Route::get('clients', 'ClientsController#index')->name('clients');
Route::delete('clients/{id}', 'ClientsController#destroy');
Route::resource('projects', 'ProjectsController', array('only' => array('show')));
});
I've tried no_auth and it just breaks. Am I missing something?
You should set the redirect path for when a given visitor is authenticated user.
You can do so in: App\Http\Middleware\RedirectIfAuthenticated
Example:
public function handle($request, Closure $next)
{
if ($this->auth->check()) {
return redirect('/dashboard');
}
return $next($request);
}
Stackoverflow: laravel redirect if logged in
You want to redirect already registered user to Homepage whenever they try to hit /login.
Here's how laravel tries to achieve that.
Firstly this is achieved through App\Http\Middleware\RedirectIfAuthenticated.
However a key to this middleware is registered to guest in this file app\Http\Kernel.php under array protected $routeMiddleware.
Then in your login controller presumably at app\Http\Controllers\Auth\LoginController.php
In the construct method, We have something like this:
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/';
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}

How to use middleware on routes in laravel?

I need to implement a little functionality for my application.
I have a form for editing and only admin must have access to it.
I can't figure out how to arrange the routes correctly, because I get
"The site has redirected too many times."
middleware:
class AdminMiddleware
{
public function handle($request, Closure $next)
{
$user = new User();
if ($user->role_id !==1) {
return redirect('/');
}
return $next($request);
}
}
route:
Route::post('/product', 'IndexController#store');
Route::get('/product', 'IndexController#index');
Route::get('/product/create', 'IndexController#create');
Route::put('/product/{product}', 'IndexController#update');
Route::get('/product/{product}/edit', 'IndexController#edit')->middleware('admin');
This route should be available only for admin
'/product/{product}/edit'
What am I doing wrong?

Laravel 5 restrict access to pages using middleware

I am working on a laravel project and i need to restrict access to some pages such that only authenticated users can view that page.
To do this, created a middleware: php artisan make:middleware OnlyRegisteredUser
and registered it in the $routemiddleware inside App\Http\kernel.php as
'onlyregistereduser' => \App\Http\Middleware\OnlyRegisteredUser::class,
and this is the class. it redirects user to auth/login if not logged in
public function handle($request, Closure $next, $right=null)
{
$user = $request->user();
if ($user && $user->onlyregistereduser()) {
return $next($request);
}
return redirect('auth/login');
}
Here is my route:
Route::get('admin/poem', ['middleware' => 'onlyregistereduser:admin', 'uses'=>'PoemsController#poem']);
admin is a parameter passed to my middleware. It is taken from my user model which has an `enum' column as follows:
public function up()
{
Schema::create('users', function (Blueprint $table) {
//...
$table->enum('rights', ['admin', 'guest'])->nullable();
// ...
});
}
Now to restrict access to some of my controller methods, e.g create, i added a constructor to my PoemsController as shown:
public function __construct()
{
$this->middleware('onlyregistereduser');
}
My problem now is that this caused every single route to the PoemsController to redirect me to the login page. And again after login in, it doesn't take me to the page i intended to visit. it takes me instead to the home page. What i want is to restrict access to only some of the controller methods and not all of them and to be able to redirect to the intended page after user login.
I hope you understand my problem.
Any help will be greatly appreciated.
Remove the middleware from constructor, you don't have to add middleware to both route and costructor. That should solve your ". What i want is to restrict access to only some of the controller methods and not all of them" issue.
For othe issue modify your middleware like this
public function handle($request, Closure $next, $right=null)
{
$user = $request->user();
if ($user && $user->onlyregistereduser()) {
return $next($request);
}
$request_url = $request->path();
session()->put('login_refferrer', $request_url);
return redirect('auth/login');
}
and before redirect user after login
if(session()->has('login_refferrer')){
$url = session()->pull('login_refferrer');
return redirect($url);
}

Laravel 5.2 Redirect admin page after login as admin

Laravel 5.2 has been out for some time now. Yes, it has new auth function which is very good. Specially for beginners.
My question,
How to check if user is admin and then redirect safely to admin/dashboard properly? I know one way is to use admin flag in database but can any of you show some example?
go to AuthController.php and add this method
where role is the user role as defined in the database.
protected function authenticated($request,$user){
if($user->role === 'admin'){
return redirect()->intended('admin'); //redirect to admin panel
}
return redirect()->intended('/'); //redirect to standard user homepage
}
As in Laravel 5.3 / 5.4
Add following line to create_users_table migration.
$table->boolean('is_admin');
Add following method to LoginController.
protected function authenticated(Request $request, $user)
{
if ( $user->is_admin ) {
return redirect('/admin/home');
}
return redirect('/home');
}
Additional note don't forget to add the following lines to RedirectIfAuthenticated middleware:
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
// the following 3 lines
if (Auth::user()->is_admin) {
return redirect('/admin/home');
}
return redirect('/home');
}
return $next($request);
}
Otherwise if you e.g. type yourdomain/login and your logged in as admin it would be redirected to home instead of admin/home.
AuthController extends the AuthenticatesAndRegistersUsers trait, which has a public method named redirectPath. In my case I would extend that method on the AuthController and I'd put my logic there:
public function redirectPath()
{
if (Auth::user->myMethodToCheckIfUserHasAnAdminRoleLikeAnEmailOrSomethingLikeThat()) {
redirect('admin/dashboard');
}
redirect('home');
}
in Auth/LoginController there is protected $redirectTo = '/home';
change '/home' to '/loginin' for example, and create a new controller and in the controller get the information of the user and check if he is a admin or not and then redirect him to the proper page

Resources