How works RedirectIfAuthenticated.php? - php

I ran php artisan make:auth in Laravel 5.6 as it is well known this did generated a HomeController.php file.
Inside that:
public function index(){
return view('home');
}
and Route::get('/home', 'HomeController#index')->name('home'); route definition into web.php.
But http://homestead.test/home URI redirect to http://homestead.test/login due RedirectIfAuthenticated.php middleware. So RedirectIfAuthenticated.php works as global middleware instead route middleware although is defined in $routeMiddleware property in Kernel.php.
Why does this happen?
What do I not know?

If you look at the constructor of the controller that was created it is using the auth middleware.
$this->middleware('auth');
If you look at your Kernel.php at $routeMiddleware:
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
This doesn't involve RedirectIfAuthenticated at all. That would redirect any users who are already authenticated away from a route. The auth middleware redirects everyone who isn't authenticated to a route, 'login'.

Related

using Laravel 7 Api routes

I'm trying to use simple laravel api for getting and sending requests, after define this api routes in api.php:
Route::prefix('Api/v1')->group(function () {
Route::any('login', 'Api\v1\AuthController#login');
Route::any('register', 'Api\v1\AuthController#register');
});
and creating AuthController in app/http/controller/Api/v1 directory:
class AuthController extends Controller
{
public function login()
{
dd(request()->all());
}
public function register()
{
dd(request()->all());
}
}
i get 404 error on this link:
http://127.0.0.1:8000/Api/v1/login
how can i resolve this problem?
Routes in api.php are automatically prefixed with /api. Currently, your routes are:
http://127.0.0.1:8000/api/Api/v1/login
http://127.0.0.1:8000/api/Api/v1/register
So navigating to http://127.0.0.1:8000/Api/v1/login is a 404.
If you remove /Api, and just use Route::prefix('/v1') ... then you should have no issue.
Also, always double check your routes with php artisan route:list to see what's wrong.
The API Routes are already prefixed by /api . I think the correct structure you'd looking for would be
Route::prefix('v1')->group(function () {
Route::any('login', 'AuthController#login');
Route::any('register', 'AuthController#register');
});
This way, you're calling the methods Login and Register from you /Controllers/AuthController file with the route
http://127.0.0.1:8000/api/v1/login
You can use many ways to define routes for API in laraval > routes > api.php file.
In this i'm going to explain how we can use routes group in the laraval..
Route::group([
'namespace' => 'Customers', //namespace App\Http\Controllers\Customers;
'middleware' => 'auth:api', // this is for check user is logged in or authenticated user
'prefix' => 'customers' // you can use custom prefix for your rote {{host}}/api/customers/
], function ($router) {
// add and delete customer groups
Route::get('/', [CustomerController::class, 'index']); // {{host}}/api/customers/ this is called to index method in CustomerController.php
Route::post('/create', [CustomerController::class, 'create']); // {{host}}/api/customers/create this is called to create method in CustomerController.php
Route::post('/show/{id}', [CustomerController::class, 'show']); // {{host}}/api/customers/show/10 this is called to show method in CustomerController.php parsing id to get single data
Route::post('/delete/{id}', [CustomerController::class, 'delete']); // {{host}}/api/customers/delete/10 this is called to delete method in CustomerController.php for delete single data
});
You can create controller using artisan command with default methods
php artisan make:controller Customers/CustomerController --resource

Problem in my test function trying to access group of routes

What I'm trying to test is to access some routes but these routes are in laratrust role middleware this role is the auth user must be super admin to go in this routes my problem is I don't know how to write this function.
I tried to make the user super admin in the test function like this
public function Test()
{
$user = factory(User::class)->create();
$user->attachRole('superadministrator');
$this->actingAs($user, 'api');
$response = $this->json('GET', 'api/users');
$response->assertStatus(200);
}
but it didn't work even I checked the data base this user is superadministrator and the test give like I'm not super admin
This is my api routes:
Route::group(['middleware' => ['auth:api', 'role:superadministrator']],
function()
{
Route::apiResource('users', 'UserController');
}
This is my index function in UserController:
public function index()
{
return Response()->json(User::all, 200);
}
What I'm expect is a function can access this route because there is more routes in this group and the rest of the tests depends on this function
I've never used Laratrust, but after a quick look at its source code, it looks like the issue is that you need to specify the api guard on your role middleware check. Add ,guard:api to your role middleware:
Route::group(['middleware' => ['auth:api', 'role:superadministrator,guard:api']], function() {
Route::apiResource('users', 'UserController');
}
In the role middleware check, if you don't specify the guard, it will use the default guard defined in your auth config (which is web if you haven't changed it). So, the middleware will be looking for the user from the web auth guard, which doesn't exist.
The good news is, your test worked! It found a bug in your route definition.

Using session in custom middleware in laravel

I've simple middleware which checks if there is a key in user session.
<?php
namespace App\Http\Middleware;
use Closure;
class CustomAuth
{
public function handle($request, Closure $next)
{
if($request->session()->has('uid')){
return $next($request);
}
else{
return view('unauth');
}
}
}
The problem is that I always get "Session store not set on request." error. Here is my route:
Route::get('home', function () {
return view('home');
})->middleware('web', 'CustomAuth');
I've added the middleware in app\Http\Kernel.php in the variable $middleware
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\CustomAuth::class
];
I also tried changing my route to this:
Route::group(['middleware' => ['web']], function () {
Route::get('home', function () {
return view('home');
})->middleware('CustomAuth');
});
But this didn't work. Any idea how I can make sure that the session had started, or start it before the middleware is called? I'm using Laravel 5.3
The L5 middleware consists of 3 "types".
The configuration is found in the Kernel.php file for HTTP requests (typically App\Http\Kernel. There's global middleware which will run for all requests and is declared in $middleware, there's the route group middleware which will run for all requests for a given route group and is declared in $middlewareGroups, by default all routes declared in web.php are considered to be web routes so all the web middleware apply.
The 3rd type is route middleware. These are declared in the $routeMiddleware array in the form "middlewareName" => Middleware::class and can be used in any route e.g.
Route::get("/route", function () { /* route body */ })->middleware("middlewareName");
These run in order global > group > route middleware and the SessionStart middleware runs as part of the group middleware. Any other middleware that needs access to the session will need to be placed after the SessionStart middleware.
Clarification
It occurs to be when re-reading this that this implies that you need to declare the middleware in the $middeware variable to use them. This is not the case, the following syntax is also allowed:
Route::get("/route", function () {
/* route body */
})->middleware(Middleware::class);
However this syntax will not allow you to provide parameters to the middleware when you use them as you would for example with the authentication middleware when you do auth:api (where api would be a parameter passed to the middleware).

Check the user's auth in all controllers' actions

I use Laravel 5.3 and I have the following problem.
[UPDATE]
My initial trouble was the appearance of an error when performing actions on the site when the user was not logged in the system.
This happened when the browser is started, where cached information is displayed by default on the page. Site interface displayed for logged users, and in his system was not. At the same time, producing some action, I get an error that the user is not authorized.
I also have group auth middleware for all my routes. When I reboot page of the site, the middleware is activated and redirectedme to the login page. The main problem is the browser shows the cached information.
So, in addition to middleware for routes I decided to make auth check in controllers.
[/UPDATE]
I want to check user's auth in every controller's action. Making the auth check in every controllers' action manually isn't a solution, because there are many controllers and actions.
So I decided to make it globally.
As all controllers extends Main Controller (App\Http\Controllers\Controller.php), I decided write the
auth()->check() in constructor:
function __construct()
{
if(auth()->check()) dd('success');
}
But... nothing happened((( Then I found the callAction method in BaseController which Main Controller extends and made checking here:
public function callAction($method, $parameters)
{
if(auth()->check()) dd('success');
return call_user_func_array([$this, $method], $parameters);
}
This time everything's OK, but I don't like this solution, because editing the core files isn't good.
Finally, I redeclared callAction method in Main Controller with auth checking, but I don't like this way too.
Is any solution?
You should use middleware:
Route::get('profile', ['middleware' => 'auth', 'uses' => 'UserController#showProfile']);
Or:
Route::get('profile', 'UserController#show')->middleware('auth');
Or using middleware groups:
Route::group(['middleware' => ['auth']], function () {
// Controllers here.
});
Or using controller's construct:
public function __construct()
{
$this->middleware('auth');
}
You can use auth middleware in your controller
public function __construct()
{
$this->middleware('auth');
}
check here : https://laravel.com/docs/5.3/authentication
if there is a group of routes this would be the easiest way
Route::group(['middleware' => ['auth']], function()
{
// here all of the routes that requires auth to be checked like this
Route::resource('user','UsersController');
}
another ways
function __construct()
{
$this->middleware('auth');
}
another way is specified on controller routes
Route::get('profile', [
'middleware' => 'auth',
'uses' => 'UserController#showProfile'
]);
see documentation
https://laravel.com/docs/5.0/controllers#controller-middleware

Call separate Route after Register and login in laravel 5.2 Auth?

I want to call separate Route after registration and login in laravel 5.2 Auth.like after login call dashboard Route and after registration call add_project Route??
**protected $redirectTo = '/dashboard';**
how i play with it?? for that specific case.
The best method is to use the Auth middleware built in to laravel. You can setup a default login route which unathenticated routes should be sent to, and allow all authenticated users into the route.
This is the best method because it can be applied to a group of routes, meaning you don't have to manually add the rule to each route you want protected. Just group them together.
Route::group(['prefix' => 'auth', 'namespace' => 'Auth'], function () {
Route::any('login', 'AuthenticationController#anyLogin');
});
Route::group(['middleware' => 'auth'], function () {
Route::resource('person', 'PersonController');
});
Open /App/Http/Controllers/Auth/AuthController.php and change line 31 shown below.
protected $redirectTo = '/';
to
protected $redirectTo = '/dashboard';
Now open file /vendor/laravel/framework/src/Illuminate/Foundation/Auth/RegistersUsers.php. here inside the register method on line 53, right after this line:
$validator = $this->validator($request->all());
add this line:
$this->redirectPath = '/add_project';
So here the $redirectTo path is used for both register and login redirection. after the first change, successful login will redirect to the dashboard. but registration will redirect there too. so we have to modify the redirectPath() method which as final proccess is responsible for the redirection. this method (AuthController > RegistersUsers trait register method > RedirectsUsers trait > redirecPath method) checks the 'redirectPath' property before it redirects to the default '$redirectTo' path which we changed first. By adding the property the check will redirect directly to the 'redirectPath' path.

Categories