I have a bunch of controllers. One of them is ArticleController. I want the method postCreateArticle() method to require the user to be authenticated.
In the documentation, I figured you can use the auth middleware, like so:
Route::get('profile', ['middleware' => 'auth', function()
{
// Only authenticated users may enter...
}]);
However, I am registering my controllers in the routes:
Route::controller('articles', 'ArticleController');
How do I protect the postCreateArticle() method, without doing it inside the method?
In your constructor you should be able to:
$this->middleware('auth', ['only' => 'postCreateArticle'])
Related
For apis auth I am currently using:
Route::group([
'middleware' => 'auth:api'
], function() {
Route::post('logout', 'AuthController#logout');
Route::get('user', 'AuthController#user');
});
If I want to use same for session based logins do I need to create same routes in web.php file or can I set up middleware in AuthController constructor with something like this or this?
In this answer 'auth:api' means auth is checking for api so do I need to pass anything there to check for sessions like 'auth:api,web' or what?
Create same routes in web.php just ommit the middleware, as web middleware is applied automatically. Same goes for api.php, auth:api is default middleware there.
I need to configure middleware in Laravel that all controllers will be secured by Auth.
I mean that will redirection for every incoming request if user is not authorized.
You can do the following in your routes file:
Route::group(['prefix' => 'admin'], function () {
Route::group(['middleware' => ['auth'], function() {
...Your routes here
This will apply the auth middleware to all routes prefixed with admin. You can of course also leave the prefix away if you don't need it.
I have a route defined as:
Route::resource('item', 'ItemController');
What I want to do is put some of these routes, particularly edit and delete inside a group.
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'delete']]);
}
This doesn't work, though. Do I have to define each route one by one then? Or is there a better solution to this?
EDIT:
I'm sorry, but it seems I did not ask the question properly. So let me make some clarifications here.
I have a basic auth user which can create and view items. What I don't want it to do is edit and delete.
I then also have a role user which do everything auth can do AND edit and delete items.
So basically, regular authorized users can have SOME access to items while role users have COMPLETE access.
The current code seems to give role users ONLY edit and delete functionalities and no view or create.
To make it even more clearer, here's what my actual route looks like:
Route::group(['middleware' => ['auth']], function()
{
Route::resource('items', 'SitesController');
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'delete']]);
});
});
Maybe I'm going about this the wrong way?
The code above will work, you just named the action incorrectly. You should have used destroy instead of delete. Try the following code:
Route::resource('item', 'ItemController');
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'destroy']]);
});
You can run php artisan route:list to verify. You should see role middleware enabled in 2 of your routes.
I have a laravel app with 2 groups of routes:
Route::group(array('prefix' => 'api'), function()
{
Route::post('/login', ['uses' => 'AuthenticationController#apiLogin']);
}
Route::group(array('prefix' => 'admin'), function()
{
Route::post('/login', ['uses' => 'AuthenticationController#adminLogin']);
}
In an effort to save time and prevent writing double code I'd like to condense the apiLogin() and adminLogin() function to one function: login(). I'd also like to return different things based on the route that is calling the function.
If the request is coming from /api/login I want to return Response::json($apiResponse). If the request is coming /admin/login I want to return Redirect::('route.to.redirect.to')
Is there a way I can tell where the controller function is being called from? (preferable without parsing the URL)
You can check the route in your controller. (I'm not saying this is the best solution for your problem, but you can)
The best way to do this is by naming your routes. Laravel Docs
Route::post('/login', ['as' => 'apiLogin', 'uses' => 'AuthenticationController#apiLogin']);
Route::post('/login', ['as' => 'adminLogin', 'uses' => 'AuthenticationController#adminLogin']);
And then you just do
Route::currentRouteName();
If for some reason you can't name your routes you can still get the path of the route (that's not the full url but the segment that's defined in the route. groups included)
So Route::getCurrentRoute()->getPath() should return either api/login or admin/login
You can check URL in controller, but the better solution in this case would be probably leaving routes as they are, create login method with parameter:
public function login($from) {
}
and define apiLogin and adminLogin functions this way:
public function apiLogin() {
return $this->login('api');
}
public function adminLogin() {
return $this->login('admin');
}
this way, if you will decide in future to change the code you will change the code only of those methods, leaving routes without a change.
I try to learn Laravel, and I'd like to verify the user is logged in before calling a controller to do stuff.
There seems to be at least 3 different ways to accomplish this, and I'd like to know what is the difference between these.
Route::get('/main', 'StuffController#doStuff')->before('auth');
Route::get('/main', array('before' => 'auth', 'uses' => 'StuffController#doStuff'));
Or in the controllers constructor:
public function __construct() {
$this->beforeFilter('auth');
}
There are no differences. Laravel is the Framework that allow you to accomplish many tasks in many ways.
I prefer to add filters in routes grouping them, for example:
// logged users paths
Route::group(
['before' => 'auth'],
function () {
Route::get('/dashboard', [
'as' => 'dashboard',
'uses' => 'DashboardController#mainPage'
]);
}
);
// paths only for admin
Route::group(
['before' => 'admin'],
function () {
Route::get('/admin',
['as' => 'admin_dashboard',
'uses' => 'AdminDashBoardController#mainPage'
]);
Route::get('/categories/{page?}',
['as' => 'categories',
'uses' => 'CategoryController#displayList'
])->where('page', '[1-9]+[0-9]*');
}
);
There is one benefit of such use - its' much easier to look if all routes have correct filters.
Assume you want to display some content only for logged users and you need to use auth filter. You have many controllers to display content for logged users.
If you use beforeFilter directly in those controllers or in parent controllers constructor the following things can happen:
you may forget to put beforeFilter in all your controller constructors
you may forget in your controller constructor to run parent constructor (where you have beforeFilter)
you may extend not the class you wanted (for example you extend BaseController and you have beforeFilter defined in AuthController and in one or some classes you extend BaseController)
Those situations can cause that you display content for unlogged users because you need to remember about auth filter it in each controller and if you want to make sure you did everything right, you need to look at code of all your controllers.
Using route grouping (as I showed above) you can easily look at one file (of course assuming you use one file for routing) and you will see which routes use auth filter and which don't.
Of course I assume many people will have their own opinion on that thing but that's me personal preference to use filters in routes.
Your two ways have no difference, just different syntax style.
I prefer to put the auth filter in a BaseController, then extends all controllers I want to be authed from BaseController. Just write once, used everywhere. Btw, you can also put your csrf filter here.
class BaseController extends Controller {
public function __construct() {
$this->beforeFilter('auth');
$this->beforeFilter('csrf', array('on' => 'post'));
}
}