I have an admin account and user acount so
I want to make an online user become out and deny all navigation immediately from my admin account when i set $user->active to 0:
$user->active = 0;
You want to logout the user once the status changed to inactive?
If this is the case you can do
public function updateUserStatus(){
$user = Auth::user();
$user->active = false;
$user->save();
Auth::logout();
return redirect("/home");
}
I have decided to use a middleware :
step 1: in terminal
php artisan make:middleware ActiveCompt
Step 2 set the middleware :
<?php
namespace App\Http\Middleware;
use Auth;
use Closure;
class ActiveCompt
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (Auth::check()){
if ($request->user()->statut == 1) {
return redirect('logout');
}
}
return $next($request);
}
}
step 3 : defining the route Of. in karnel.php
protected $routeMiddleware = [
.
.
.
'ActiveCompt' => \App\Http\Middleware\ActiveCompt::class,
];
step 4 : calling the middleware ActiveCompt from the constructors
$this->middleware('ActiveCompt');
Related
I want to implement Impersonate functionality into Laravel-8 without using any package.
Only super-admin can use this functionality.
I used laravel sanctum to authenticate.
to access impersonate functionality user should be super-admin. (is_admin(boolean) flag is set into users table).
Here is my middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ImpersonateUser
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$impersonateId = $request->cookie('x-impersonate-id');
if($request->user()->is_admin && $impersonateId) {
$user = User::findOrFail($impersonateId);
if($user->is_admin) {
return response()->json(["message" => trans("You cannot impersonate an admin account.")], 400);
}
Auth::setUser($user);
}
return $next($request);
}
}
My route file:
// Impersonate routes.
Route::middleware(['auth:sanctum', 'impersonate'])->group(function () {
// checklist routes
Route::get('checklists', [ChecklistController::class, "index"]);
});
Whether use Auth::setUser($user) is safe or I have to use Auth::onceUsingId($userId); ?
Auth::onceUsingId($userId); not working with auth::sanctum middleware. So Auth::setUser($user) is safe or not?
I used laravel to develop backend API only.(SPA)
They should be the same in terms of safety. OnceUsingId() calls setUser() in the background.
From the Illuminate\Auth\SessionGuard class
/**
* Log the given user ID into the application without sessions or cookies.
*
* #param mixed $id
* #return \Illuminate\Contracts\Auth\Authenticatable|false
*/
public function onceUsingId($id)
{
if (! is_null($user = $this->provider->retrieveById($id))) {
$this->setUser($user);
return $user;
}
return false;
}
/**
* Set the current user.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #return $this
*/
public function setUser(AuthenticatableContract $user)
{
$this->user = $user;
$this->loggedOut = false;
$this->fireAuthenticatedEvent($user);
return $this;
}
Both of these methods come from the SessionGuard though. I don't know if Sanctum implements its own version.
The Scenario
I have a simple application which has four main user roles.
Admin (AdminController and Admin middleware file)
Moderator (ModeratorController and Moderator middleware file)
Agent (AgentController and Agent middleware file)
Supplier(SupplierController and Supplier middleware file)
Each role has a separate controller and middleware as above. Every controller has index method which directs the controller to the respected home view.
AdminController File
class AdminController extends Controller
{
public function index()
{
return view('admin.home');
}
}
Note : same goes to other 3 controller files with respect to each role.
Middleware\Admin.php file
use Auth;
class Admin
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
//return $next($request);
if(auth::check() && Auth::user()->role == 1){
return $next($request);
}
else {
return redirect()->route('login');
}
}
}
Note : same goes to other 3 middleware files with respect to each role.
Kernal.php
protected $routeMiddleware = [
...
'admin' => \App\Http\Middleware\Admin::class,
'moderator' => \App\Http\Middleware\Moderator::class,
'agent' => \App\Http\Middleware\Agent::class,
'supplier' => \App\Http\Middleware\Supplier::class,
];
routes\web.php
Route::get('/admin', 'AdminController#index')->middleware('admin');
Route::get('/moderator', 'ModeratorController#index')->middleware('moderator');
Route::get('/agent', 'AgentController#index')->middleware('agent');
Route::get('/supplier', 'SupplierController#index')->middleware('supplier');
\App\Http\Middleware\RedirectIfAuthenticated
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if ($guard == "admin" && Auth::guard($guard)->check()) {
return redirect('/admin');
}
if ($guard == "moderator" && Auth::guard($guard)->check()) {
return redirect('/moderator');
}
if ($guard == "agent" && Auth::guard($guard)->check()) {
return redirect('/agent');
}
if ($guard == "supplier" && Auth::guard($guard)->check()) {
return redirect('/supplier');
}
return $next($request);
}
}
Finally my LoginController
use Auth;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo;
public function redirectTo()
{
switch(Auth::user()->role){
case 1:
$this->redirectTo = '/admin';
return $this->redirectTo;
break;
case 2:
$this->redirectTo = '/moderator';
return $this->redirectTo;
break;
case 3:
$this->redirectTo = '/agent';
return $this->redirectTo;
break;
case 4:
$this->redirectTo = '/supplier';
return $this->redirectTo;
break;
default:
$this->redirectTo = '/login';
return $this->redirectTo;
}
// return $next($request);
}
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
//$this->middleware('guest')->except('logout');
}
}
QUESTIONS
Q1. Is this the best way or rather most efficient way to achieve this?
Q2. Is this approach is secure enough to use in a real commercial application?
Q3. The routes work the way they are expected to work, For an instance if i go to localhost/login and type relevant credentials it goes to the relevant home page based on the user role. And when i'm in localhost/admin and try to type and go to url localhost/agent it simply goes to the login localhost/login without logout the user.
However if the user doesn't want to try another login or rather want to go back to his dashboard, the app can't recognize the logged user's correct home to go back when click on the "Dashboard". When click, it redirects to the /home created by default Auth scaffolding which i have already removed from the app structure. Same apply to other user roles eg; from localhost/agent to localhost/supplier, from localhost/moderator to localhost/admin, etc.
What am i missing here?
Please note that i started working with laravel few weeks back and still trying to figure the things out...
The middleware of RedirectIfAuthenticated is responsible for redirecting users that are currently authenticated in the site.
You should apply your logic in redirectTo method of App\Http\Controllers\Auth\LoginController if you're using laravel/ui
I have been trying to redirect a user after login, there are two links that should be redirected to when a certain condition is fulfilled.
protected function redirectTo(){
$userRole = User::findOrFail(Auth::id());
// dd($userRole->roles);
if($userRole->roles == 'admin'){
return 'admin/controlpanel';
}
elseif ($userRole->roles == 'participant') {
return 'student/profile';
}
}
I created this function to redirect but it still redirect to '/home'. Then I read over here and on git that I also had to the modify RedirectIfAuthenticated model in the middleware, I did this
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use App\User;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return self::redirectTo();
}
return $next($request);
}
protected function redirectTo(){
$userRole = User::findOrFail(Auth::id());
if($userRole->roles == 'admin'){
return 'admin/controlpanel';
}
if ($userRole->roles == 'participant') {
return 'student/profile';
}
}
}
but is still keeps giving me this error in my previous question
here
I reverted to my previous git commit, then coded step by step till I discovered it was coming from the middleware I modified...
use redirect helper like this: return redirect('admin/controlpanel');
When my users register in my app it automatically redirects them to /dashboard which is technically fine, but it isn't checking to see if the confirmed column in the database has a value of 1 or 0, it's just logging in based on the username and password.
I will happily include code but right now I don't actually know what code you guys need to see.
I need it to check the confirmed column and if it's a 0, not to log them in and throw and error.
thanks for any info,
Andy
I achieve this by utilizing middleware:
My routes.php:
Route::get('home', ['middleware' => 'auth', function () {
return "This is just an example";
}]);
My Kernel.php:
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
];
My Authenticate.php middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class Authenticate
{
/**
* The Guard implementation.
*
* #var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* #param Guard $auth
* #return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('auth/login');
}
}
$user = $this->auth->user();
if (!$user->confirmed) {
$this->auth->logout();
return redirect()->guest('auth/login')->with('error', 'Please confirm your e-mail address to continue.');
}
if (!$user->type) {
$this->auth->logout();
return redirect()->guest('auth/login')->with('error', 'A user configuration error has occurred. Please contact an administrator for assistance.');
}
return $next($request);
}
}
I tried to cut this down as much as possible for you.
I'm new to laravel 5.1.
How can I use middleware parameter to protect my admin routes from users ?
something like this:
Route::group(['middleware' => 'auth:admin'], function()
/* Admin only Routes*/
{
//////
});
I have a field "role" in my "users" table that get two values:
1 for admin
2 for users
In my application, users, have their protected route.
I don't want to use packages.
You can do something like this. Inject the Guard class, then use it to check the user. You dont need to pass the parameter really. Just name your middleware 'admin' or something. The following middleware will check if the current user's role is admin, and if not, redirect to another route. You can do whatever you prefer on failure.
<?php
namespace Portal\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class Admin
{
/**
* The Guard implementation.
*
* #var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* #param Guard $auth
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if($this->auth->user()->role != 'admin') {
return redirect()->route('not-an-admin');
}
return $next($request);
}
}
In case you do want to pass the parameter, you can do this:
public function handle($request, Closure $next, $role)
{
if($this->auth->user()->role != $role) {
return redirect()->route('roles-dont-match');
}
return $next($request);
}