Laravel 5 - before auth not working - php

Today I tried to make some changes to my application. I tried to pass all pages through authentication first. I tried one of the answer on this site. But that didn't help. Please help. Here's my code in routes.php
<?php
Route::get('/', function(){
return view('homepage');
});
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
Route::group(['before' => 'auth'], function () {
Route::get('home', function(){
return \Redirect::to('twitter');
});
Route::get('twitter', 'HomeController#index');
.
.
.
.
});
There are several routes in my file. But only twitter route works.

In laravel 5,
['before' => 'auth']
is deprecated. But instead, I should use
['middleware' => 'auth']

Laravel5 has middlewares instead of filter. I assume you are trying to show certain page to only guests and for that we have a guest middleware already built in.
Route::group(['middleware' => 'guest'], function () {
Route::get('home', function(){
return \Redirect::to('twitter');
});
Route::get('twitter', 'HomeController#index');
});
you may also use middlewares on particular functions of your controller if you want, e.g
class MyController extends Controller {
public function __construct()
{
//to add auth middleware only on update method
$this->middleware('auth', ['only' => 'update'])
//to add auth middleware on all fucntions expcept login
$this->middleware('auth', ['except' => 'login'])
}
}

Related

Laravel auth0 doesnt "remember" user

So i have been working with Laravel and Auth0 for some time now and i think i am at the end :)
I am able to log into my application using a link to the widget / hosted page
Now everything seems to be working and once the page callbacks to my site the user I saved in my database.
However, it doesn't seem that my application remembers the user.
When i attempt to check if a user is logged in:
$isLoggedIn = \Auth::check();
it says false
I have tried debugging multiple functions however with no results so i am kind of lost on where to start with this.
Does anyone know why this is happening?
My configuration
So this is my AuthController:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class AuthController extends Controller
{
public function __construct()
{
}
public function login()
{
return \App::make('auth0')->login(null, null, ['scope' => 'openid profile email'], 'code');
}
public function logout()
{
\Auth::logout();
return \Redirect::intended('/');
}
public function dump()
{
$isLoggedIn = \Auth::check();
return view('dump')
->with('isLoggedIn', $isLoggedIn)
->with('user',\Auth::user()->getUserInfo())
->with('accessToken',\Auth::user()->getAuthPassword());
}
}
Then in my web:
Route::get('/login', ['as' => 'login', 'uses' => 'AuthController#login']);
Route::get('/logout', ['as' => 'logout', 'uses' => 'AuthController#logout'])->middleware('auth');
Route::get('/dump', ['as' => 'dump', 'uses' => 'AuthController#dump', 'middleware' => 'auth'])->middleware('auth');
Route::get('/auth0/callback', '\Auth0\Login\Auth0Controller#callback');

Apply Middleware to all routes except `setup/*` in Laravel 5.4

I'm experimenting with Middleware in my Laravel application. I currently have it set up to run on every route for an authenticated user, however, I want it to ignore any requests that begin with the setup URI.
Here is what my CheckOnboarding middleware method looks like:
public function handle($request, Closure $next)
{
/**
* Check to see if the user has completed the onboarding, if not redirect.
* Also checks that the requested URI isn't the setup route to ensure there isn't a redirect loop.
*/
if ($request->user()->onboarding_complete == false && $request->path() != 'setup') {
return redirect('setup');
} else {
return $next($request);
}
}
This is being used in my routes like this:
Route::group(['middleware' => ['auth','checkOnboarding']], function () {
Route::get('/home', 'HomeController#index');
Route::get('/account', 'AccountController#index');
Route::group(['prefix' => 'setup'], function () {
Route::get('/', 'OnboardingController#index')->name('setup');
Route::post('/settings', 'SettingsController#store');
});
});
Now, if I go to /home or /account I get redirected to /setup as you would expect. This originally caused a redirect loop error hence why & $request->path() != 'setup' is in the Middleware.
I feel like this is a really clunky way of doing it, and obviously doesn't match anything after setup like the setup/settings route I have created.
Is there a better way to have this Middleware run on all routes for a user, but also set certain routes that should be exempt from this check?
There's nothing wrong with what you're doing, however, I would suggest splitting your route groups up instead i.e.:
Route::group(['middleware' => ['auth', 'checkOnboarding']], function () {
Route::get('/home', 'HomeController#index');
Route::get('/account', 'AccountController#index');
});
Route::group(['prefix' => 'setup', 'middleware' => 'auth'], function () {
Route::get('/', 'OnboardingController#index')->name('setup');
Route::post('/settings', 'SettingsController#store');
});
Alternatively, have a parent group for your auth:
Route::group(['middleware' => 'auth'], function () {
Route::group(['middleware' => 'checkOnboarding'], function () {
Route::get('/home', 'HomeController#index');
Route::get('/account', 'AccountController#index');
});
Route::group(['prefix' => 'setup'], function () {
Route::get('/', 'OnboardingController#index')->name('setup');
Route::post('/settings', 'SettingsController#store');
});
});
This will also mean you can remove the extra condition in your middleware:
/**
* Check to see if the user has completed the onboarding, if not redirect.
* Also checks that the requested URI isn't the setup route to ensure there isn't a redirect loop.
*/
return $request->user()->onboarding_complete ? $next($request) : redirect('setup');
Hope this helps!
You can utilize the Controller class for this with pretty spectacular results.
If you create a __construct function inside of HTTP/Controllers/Controller.php then you can declare middleware to run on every controller action and even declare exceptions as needed.
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function __construct(){
$this->middleware('auth',['except' => ['login','setup','setupSomethingElse']]);
}
}
Be careful not to put any of the standard index, store, update, destroy functions in the exception or you'll open up potential security issues.
Since Laravel 7.7 you can use excluded_middleware like this:
Route::group(['middleware' => ['auth','checkOnboarding']], function () {
Route::get('/home', 'HomeController#index');
Route::get('/account', 'AccountController#index');
Route::group([
'prefix' => 'setup',
'excluded_middleware' => ['checkOnboarding'],
], function () {
Route::get('/', 'OnboardingController#index')->name('setup');
Route::post('/settings', 'SettingsController#store');
});
});
In Laravel 8.x you can also use the withoutMiddleware() method to exclude one or many route to a group middleware
Route::middleware('auth')->group(function () {
Route::get('/edit/{id}',[ProgramController::class, 'edit'])->name('edit');
Route::get('/public', [ProgramController::class, 'public'])
->name('public')->withoutMiddleware(['auth']);
});
Check also the official doc: Here
There are 2 ways to go over this problem
Try screening your routes in routes file web.php or api.php
skip routes in middleware
In case of global middleware (middleware that you want to run before all routes), you should go with skipping routes in middleware.
For example:
//add an array of routes to skip santize check
protected $openRoutes = [
'setup/*',
];
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(!in_array($request->path(), $this->openRoutes)){
//middleware code or call of function
}
return $next($request);
}
For other middleware, you can easily skip in routes file and group routes based on your middleware.
For example:
Route::group(['middleware' => 'checkOnboarding'], function () {
Route::get('/home', 'HomeController#index');
Route::get('/account', 'AccountController#index');
});
Route::group(['prefix' => 'setup'], function () {
Route::get('/', 'OnboardingController#index')->name('setup');
Route::post('/settings', 'SettingsController#store');
});
Routes on which you dont want the middleware to run , simply put them outside of the function:
//here register routes on which you dont want the middleware: checkOnboarding
Route::group(['middleware' => ['auth','checkOnboarding']], function () {
//routes on which you want the middleware
});

Laravel route Action not defined

I am having trouble with Laravel routes. I'm trying to redirect to a controller after some middleware in the routes. But there is always this error.
The error is:
InvalidArgumentException in UrlGenerator.php line 558: Action
App\Http\Controllers\DashboardController#index not defined.
The route code is:
Route::get('/dashboard', ['middleware' => 'auth', function() {
return Redirect::action('DashboardController#index', array('user' => \Auth::user()));
}]);
The controller:
class DashboardController extends Controller
{
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
return view('dashboard')->with('user', \Auth::user());
}
}
But the above code actually works (so I guess that the controller actually works):
Route::get('/testdashboard', [
'uses' => 'DashboardController#index'
]);
So what is the problem? What is a valid route action?
This is might a better way to do it, change from
Route::get('/dashboard', ['middleware' => 'auth', function() {
return Redirect::action('DashboardController#index',
array('user' => \Auth::user()));
}]);
to
Route::get('/', [
'middleware' => 'auth',
'uses' => 'DashboardController#index'
]);
This is rather a comment than a post, but I can't send it at this time. I don't undestand why do you pass parameter (\Auth:user()) to a method that doesn't require it (but it's correct when you do it for the View).
Anyways I suggest you to work on your Middleware
public function handle($request, Closure $next)
{
if (Auth::check()) {
return redirect(...);
} else {
return redirect(...);
}
}
Use this route in place of your route and upgrade your Laravel Project to Laravel 8:
Route::middleware(['auth:sanctum', 'verified'])->group(function () {
Route::get('/dashboard', 'DashboardController#index')->name('daskboard');
});

Laravel make a resource available to only guest users

This is my route:
Route::group(array('before' => 'auth'), function() {
Route::resource('restaurants', 'RestaurantsController');
});
I want the restaurants.create to be available for guest users.
Is that possible?
Just declare the route outside of the Route Group like this:
Route::resource('restaurants', 'RestaurantsController');
Instead of this:
Route::group(array('before' => 'auth'), function() {
Route::resource('restaurants', 'RestaurantsController');
});
Then in your RestaurantsController controller add the before filter inside the __construct method like this:
public function __construct()
{
parent::__construct(); // If BaseController has a __construct method
$this->beforeFilter('auth', array('except' => array('create')));
}
So all the methods will have auth as the before filter but without the create method. If you need to add another before filter then you may add another one just after the first one like this:
public function __construct()
{
parent::__construct(); // If BaseController has a __construct method
// Add auth as before filter for all methods but not for create
$this->beforeFilter('auth', array('except' => array('create')));
// Only for create method
$this->beforeFilter('anotherFilter', array('only' => array('create')));
}
I believe you're looking for the guest filter, which should be included by default.
So change the line from:
Route::group(array('before' => 'auth'), function() {
to:
Route::group(array('before' => 'guest'), function() {

Laravel 4: protecting routes provided by a controller

I'm building a Laravel 4 app and I want to protect my admin area so it is only accessible if the user is logged in/authenticated.
What is the best way to do this?
The Laravel docs say you can protect a route like this:
Route::get('profile', array('before' => 'auth', function()
{
// Only authenticated users may enter...
}));
But what happens when my route looks like this:
Route::resource('cms', 'PostsController');
How do I protect a route that is directing to a controller?
Thanks in advance!
You could use Route Groups for this purpose.
So for example:
Route::group(array('before' => 'auth'), function()
{
Route::get('profile', function()
{
// Has Auth Filter
});
Route::resource('cms', 'PostsController');
// You can use Route::resource togehter with
// direct routes to the Resource Controller
// so e.g. Route::post('cms', 'PostsController#save');
});
You can put the filter on the constructor of your Controller like this:
public function __construct()
{
$this->beforeFilter('auth');
$this->beforeFilter('csrf', array('on' => 'post'));
$this->afterFilter('log', array('only' =>
array('fooAction', 'barAction')));
}
In your PostsController you can put a closure in the constructor to do the same before logic as the previous route.
public function __construct()
{
$this->beforeFilter(function()
{
//
});
}

Categories