LARAVEL 5.4 ROLE ON MIDDLEWARE - php

i'm trying to setup my role on routing using middleware, but everytime i log in into my system, it redirects back on my login view.
here is my routing
Route::group(['middleware' => ['auth','admin']],function(){
Route::get('dashboard','RouteController#adminDashboard');
Route::get('admin',function(){
return 'this is admin page';
});
});
and here is my middleware
public function handle($request, Closure $next)
{
if(Auth::User()->id_role == 1){
return $next($request);
}
return redirect::to('dashboard');
}
can u guys helpme.

You're missing the initial slash.
Route::group(['middleware' => ['auth','admin']],function(){
Route::get('/dashboard','RouteController#adminDashboard');
Route::get('/admin',function(){
return 'this is admin page';
});
})
Or inside your controllers declare a construct function like this:
public function __contstruct(){
$this->middleware('auth');
}
Followed by your usual functions

If login is successful then the middleware checks the id, if the id is 1 then you return the next request ($next($request);). Your redirect never occurs.
So the next request is handled by your adminDashboard function in RouteController.
You should return your view in RouteController like this:
public function adminDashboard() {
return view('your-path-to-your-dashboard');
}
and change your route to this
Route::get('/', 'RouteController#adminDashboard');

Related

Calling laravel controller inside a route

I've Laravel route with GET & POST as below
Route::get("test1","Api\TestController#test1");
Route::post("test1","Api\TestController#test1");
Now I'm trying to check some condition & if it remain true then I want to call controller else i want to show error without even going into controller.
Like:
Route::get("test1",function(){
$aaa=$_SERVER['REQUEST_URI'];
if(preg_match("/sender_id=TEST/is", $aaa)){
#Call_controller: "Api\TestController#test1"
}else{
echo "some error found"; die();}
});
How to call controller inside function of route.
I don't want to check this in controller because its a API & when i'm getting 10000+ hits per second, calling a function inside laravel load multiple dependences resulting wastage of server resources.
Same has to be done with GET & POST
While you can call the controller using (new Api\TestController())->test1(), the right way to do is:
Create a middleware (say "MyMiddleware") and add your logic in the handle() method:
public function handle($request, Closure $next)
{
$aaa=$_SERVER['REQUEST_URI'];
if (preg_match("/sender_id=TEST/is", $aaa)) {
return $next($request);
}
abort(403);
}
Now use the middleware in the route:
Route::get("test1","Api\TestController#test1")->middleware(MyMiddleware::class);
Since both your route functions are the same, you can use middleware.
Create check middleware php artisan make:middleware check
class check
{
public function handle($request, Closure $next)
{
if(preg_match("/sender_id=TEST/is", $request->getUri())) {
return $next($request);
}
else{
return "some error found";
}
}
}
And in route
Route::group(['middleware' => 'check'], function () {
Route::get("test1","Api\TestController#test1");
Route::post("test1","Api\TestController#test1");
});

Is there a way to use two authentication middlewares in laravel?

I implemented passport authentication in Laravel and the basic auth.
I have UserController and inside it, I have the constructor methode:
public function __construct()
{
$this->middleware('auth.basic.once')->except(['index', 'show']);
$this->middleware('auth:api')->except(['index', 'show']);
}
The OnceBasic middleware:
public function handle($request, Closure $next)
{
if(Auth::guard('api')->check())
return $next($request);
else
return Auth::onceBasic() ?: $next($request);
}
In the OnceBasic middleware, I'm able to check if the user authenticated using the auth:api then I prevent the authentication from trying to use the onceBasic, So it worked correctly when using the access token. But it fails when trying to authenticate using the onceBasic(email, password) because the auth:api trying to authenticate too and it fails(trying to call the redirectTo() methods inside the default \App\Http\Middleware\Authenticate.php )
My question is there a way to use both of these middlewares, to only successfully authenticate one and prevent the other from working?
My approach to using the same controller for two guards required pointing two separate groups of routes to the controllers. I provided an example in this answer to a similar question, here is the example code again:
<?php
Route::middleware(['auth:admin_api'])->group(function () {
Route::prefix('admin')->group(function () {
Route::name('api.admin.')->group(function () {
////////////////////////////////////////////////////////////
/// PLACE ADMIN API ROUTES HERE ////////////////////////////
////////////////////////////////////////////////////////////
Route::apiResource('test','App\Http\Controllers\API\MyController');
////////////////////////////////////////////////////////////
});
});
});
Route::middleware(['auth:api'])->group(function () {
Route::name('api.')->group(function () {
////////////////////////////////////////////////////////////
/// PLACE PUBLIC API ROUTES HERE ///////////////////////////
////////////////////////////////////////////////////////////
Route::apiResource('test', 'App\Http\Controllers\API\MyController');
////////////////////////////////////////////////////////////
});
});
So when an admin user goes to admin/test, it uses the admin auth guard, and when a normal user goes to /test it uses the standard auth guard. Both of these use the same controller.
I then created a base controller for my app. Here is how I determined with guard is being used to access the route in the constructor:
<?php
use Illuminate\Http\Response;
use App\Http\Controllers\Controller;
class BaseController extends Controller
{
protected $user;
protected $isAdmin = false;
public function __construct()
{
if(Auth::guard('admin_api')->check()) {
$this->user = Auth::guard('admin_api')->user();
$this->isAdmin = true;
} elseif(Auth::guard('api')->check()) {
$this->user = Auth::guard('api')->user();
$this->isAdmin = false;
} else {
return response()->json([
'message' => 'Not Authorized',
], 401);
}
}

"Route [login] not defined." Laravel 5.6 [duplicate]

Trying to play with Laravel today for the first time. I am getting the following error when I attempt to visit localhost/project/public:
InvalidArgumentException
Route [login] not defined.
app/routes.php:
<?php
Route::get('/', 'HomeController#redirect');
Route::get('login', 'LoginController#show');
Route::post('login', 'LoginController#do');
Route::get('dashboard', 'DashboardController#show');
app/controllers/HomeController.php:
<?php
class HomeController extends Controller {
public function redirect()
{
if (Auth::check())
return Redirect::route('dashboard');
return Redirect::route('login');
}
}
app/controllers/LoginContoller.php:
<?php
class LoginController extends Controller {
public function show()
{
if (Auth::check())
return Redirect::route('dashboard');
return View::make('login');
}
public function do()
{
// do login
}
}
app/controllers/DashboardController.php:
<?php
class DashboardController extends Controller {
public function show()
{
if (Auth::guest())
return Redirect::route('login');
return View::make('dashboard');
}
}
Why am I getting this error?
Try to add this at Header of your request: Accept=application/json postman or insomnia add header
You're trying to redirect to a named route whose name is login, but you have no routes with that name:
Route::post('login', [ 'as' => 'login', 'uses' => 'LoginController#do']);
The 'as' portion of the second parameter defines the name of the route. The first string parameter defines its route.
In app\Exceptions\Handler.php
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest(route('auth.login'));
}
Laravel has introduced Named Routes in Laravel 4.2.
WHAT IS NAMED ROUTES?
Named Routes allows you to give names to your router path. Hence using the name we can call the routes in required file.
HOW TO CREATE NAMED ROUTES?
Named Routes created in two different way : as and name()
METHOD 1:
Route::get('about',array('as'=>'about-as',function()
{
return view('about');
}
));
METHOD 2:
Route::get('about',function()
{
return view('about');
})->name('about-as');
How we use in views?
about-as
Hence laravel 'middleware'=>'auth' has already predefined for redirect as login page if user has not yet logged in.Hence we should use as keyword
Route::get('login',array('as'=>'login',function(){
return view('login');
}));
You need to add the following line to your web.php routes file:
Auth::routes();
In case you have custom auth routes, make sure you /login route has 'as' => 'login'
In case of API , or let say while implementing JWT . JWT middleware throws this exception when it couldn't find the token and will try to redirect to the log in route.
Since it couldn't find any log in route specified it throws this exception .
You can change the route in "app\Exceptions\Handler.php"
use Illuminate\Auth\AuthenticationException;
protected function unauthenticated($request, AuthenticationException $exception){
return $request->expectsJson()
? response()->json(['message' => $exception->getMessage()], 401)
: redirect()->guest(route('ROUTENAME'));
}
Am late to the party. if your expectation is some sort of json returned other than being redirected, then edit the exception handler so do just that.
Go to go to App\Exceptions\Handler.php
Then edit this code:
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
}
to
public function render($request, Exception $exception)
{
return response()->json(
[
'errors' => [
'status' => 401,
'message' => 'Unauthenticated',
]
], 401
);
}
Try this method:
look for this file
"RedirectifAuthenticated.php"
update the following as you would prefer
if (Auth::guard($guard)->check()) {
return redirect('/');
}
$guard as an arg will take in the name of the custom guard you have set eg. "admin" then it should be like this.
if (Auth::guard('admin')->check()) {
return redirect('/admin/dashboard');
}else{
return redirect('/admin/login');
}
I ran into this error recently after using Laravel's built-in authentication routing using php artisan make:auth. When you run that command, these new routes are added to your web.php file:
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
I must have accidentally deleted these routes. Running php artisan make:auth again restored the routes and solved the problem. I'm running Laravel 5.5.28.
Route::get('/login', function () {
return view('login');})->name('login');
Name your login route if using your own custom auth system.
Route::post('login', 'LoginController#login')->name('login')
works very well and it is clean and self-explanatory
Laravel ^5.7
The Authenticate Middleware
Laravel ^5.7 includes new middleware to handle and redirect unauthenticated users.
It works well with "web" guard... of course the "login" route (or whatever you name your login route) should be defined in web.php.
the problem is when your are using custom guard. Different guard would redirect unauthenticated users to different route.
here's a quick workaround based on John's response (it works for me).
app/Http/Middleware/Authenticate.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
/**
* #var array
*/
protected $guards = [];
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string[] ...$guards
* #return mixed
*
* #throws \Illuminate\Auth\AuthenticationException
*/
public function handle($request, Closure $next, ...$guards)
{
$this->guards = $guards;
return parent::handle($request, $next, ...$guards);
}
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* #param \Illuminate\Http\Request $request
* #return string
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
if (in_array('admin', $this->guards)) {
return route('admin.login');
}
return route('login');
}
}
}
Source : Issue #26292
Replace in your views (blade files) all
{{route('/')}} ----- by ----> {{url('/')}}
If someone getting this from a rest client (ex. Postman) - You need to set the Header to Accept application/json.
To do this on postman, click on the Headers tab, and add a new key 'Accept' and type the value 'application/json'.
**Adding this for the future me.**
I encountered this because I was reusing Laravel's "HomeController", and adding my custom functions to it. Note that this controller calls the auth middleware in its __construct() method as shown below, which means that all functions must be authenticated. No wonder it tries to take you to login page first. So, if you are not using Laravel's authentication scafffolding, you will be in a mess. Disable the constructor, or do as you seem fit, now that you know what is happening.
public function __construct()
{
$this->middleware('auth');
}
//In Laravel 8
Route::post('login', [LoginController::class, 'do'])->name('login');
If using passport as api do:
routes/web.php:
Route::get('login', function() {
return response()->json(['message' => 'Unauthorized.'], 401);
});
Route::post('login', [ 'as' => 'login']);
For Laravel 8 I face the problem while access home url after creating login register system
First there is no route exists with the name login
Just add a route name like this
for single method like
Route::post('put url here',[Your Controller::class,'method name'])->name('login');
for multiple method like
Route::match(['get','post'],'put url here',[Your Controller::class,'method name'])->name('login');
Route must be valid, should give route name.
Route::group([
'prefix' => 'v1'
], function () {
Route::post('/login', [userController::class, 'loginAction'])->name('login');
});

how to get the roles and permissions dinamically - Laravel

I'm trying to implement roles and permissions for my laravel API. I installed the package:
https://yajrabox.com/docs/laravel-acl/3.0/introduction
It would be great if someone could explain to me how it works, all I want to do is get the permission when the user hits one API route.
I don't want to set the middleware in every route, because I'm going to do several routes and it would be a pain to set middleware every time, I want do it dynamically.
I tried to do it myself but it's not working. This is my code in Authserviceprovider:
public function boot(GateContract $gate)
{
$this->registerPolicies();
Passport::routes();
Passport::tokensExpireIn(Carbon::now()->addDays(15));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
$permissions = Permission::with('roles')->get();
foreach ($permissions as $permission)
{
$gate->define($permission->name, function (User $user) use ($permission) {
return $user->hasPermission($permission);
});
}
}
I'm doing like this: https://github.com/laracasts/laravel-5-roles-and-permissions-demo/tree/master/app
You can use middleware within your web.php / api.php file such as my example (web.php) below:
Route::group(['middleware' => ['verified']], function () {
Route::get('/', 'HomeController#index')->name('home');
});
As my example shows, this will check an account is verified before allowing it to view '/'
Updated
This is almost irrelevant to the question above but as the Op asked a secondary question within the comments to my answer: here is my middleware code to show the Op how the middleware will function:
public function handle($request, Closure $next)
{
$verified = Auth::user();
if ($verified->verified == 0)
{
Auth::logout();
Session::flash('error', "$verified->username, your email address hasn't been verified yet therefore you're unable sign in.");
return Redirect('/login');
}
return $next($request);
}

Laravel Middleware - how to execute inside a controller method?

I am using multiple views for the same URL, depending if the user is logged in or not.. so mywebsite.com is routed like this:
Route::get('/', 'HomeController#redirector')->name('home');
The controller is this:
public function redirector(){
if(!\Auth::check()){
return view('welcome');
}
else{
return $this->index();
}
}
Now, when it runs the index function I need it to run the middleware 'auth', that updates and checks the user. The problem is, I cannot attach it to the route, since they might be unlogged causing a redirection loop. I tried this:
public function redirector(){
if(!\Auth::check()){
return view('welcome');
}
else{
$this->middleware('auth');
return $this->index();
}
}
It does not run the middleware.
If I put it in the costructor method attaching it to index, like this:
$this->middleware('auth', ['only' => 'index'])
it also won't run.
Any solutions to this?
if(!\Auth::check()){..} //this returns false if a user is logged in, are you sure that's what you want?
If not then remove the '!'
You can also put the redirection logic in the middleware instead. If you are using the auth middleware that ships with Laravel this is already in place. You just have to modify it as below and place the middleware call in the constructor.
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
return redirect()->guest('login');
}
return $next($request);
}

Categories