I am trying to code a login function for my api that takes a username and password then give you a password grant token to make api requests. The login route when called gives you
{
"message": "Unauthenticated."
}
I am using passport on laravel to do secure the api. Why am I getting a 401 when the route does not have the auth:api middleware? I tried using a clousure to see if I get could get a response and the closure did not give me an error.
Route::group(['prefix' => '/v1', 'middleware' => ['auth:api'], 'namespace' => 'Api\V1', 'as' => 'api.'], function () {
Route::post('/post/like','PostLikeController#store');
});
Route::group(['prefix' => '/v1', 'namespace' => 'Api\V1', 'as' => 'api.'], function () {
Route::post('login', 'Auth\LoginController#login');
});
Does your login controller have a constructor? sometimes middleware is set in there?
Otherwise I've also had issues with having the middleware routes above the public ones.
Try putting the public routes in the file first and also checking the LoginController.php for a constructor which might be setting a middleware
It possibly due to the same prefixes, as it does not overriding but instead stacking on top of each other.
I suggest for your login route, possibly, you can use this
Route::post('login', 'Auth\LoginController#login')->withoutMiddleware([FooMiddleware::class]);
If it's still does not help try putting your login route above the middlewared route.
Related
I had Laravel 4.2 application and updating it to Laravel 5.4. for this i have installed fresh Laravel 5.4 and migrated routes,controllers views etc.
I want to protect all pages after /warehouse e.g /warehouse/dashboard,/warehouse/accounts and so on except /warehouse/login page. I have searched and used this route but its not working properly.
Can any one let me know whats the proper way of authentication.
Route::group(['middleware' => ['auth']], function() {
// uses 'auth' middleware
Route::resource('/warehouse','WarehouseController#index');
});
My login and verify routes are
Route::get('/warehouse/login', array('as' => 'WarehouseAdminLogin', 'uses' => 'WarehouseController#login'));
Route::post('/warehouse/verify', array('as' => 'WarehouseAdminVerify', 'uses' => 'WarehouseController#verify'));
For Route:resource there is no need to add function name after controller.
So try this:
Route::resource('/warehouse','WarehouseController');
And for Auth middlware you can do this :
Route::middleware(['auth']->group(function() {
// Auth routes
});
And it's obvious that login route should no be inside auth middleware!
How can a new guest user see login page?
Use Auth routes outside the auth middleware :
Route::get('login', 'Auth\LoginController#showLoginForm')->name('login');
Route::post('login', 'Auth\LoginController#login');
Route::get('logout', 'Auth\LoginController#logout')->name('logout');
I have created an extra middleware admin and I want to protect my routes. Adding one single middleware 'auth' or 'auth:admin' is working.
Route::get('/calendar', function () {
return view('app', ['data' => []);
})->middleware('auth');
But I want that as an admin you can also access the user routes but this is not working. If I try the following, and I log in as an admin I get redirected to the login page all the time.
Route::get('/information', ['middleware' => ['auth', 'auth:admin'], function () {
return view('app', ['data' => ['auth' => Auth::check()]]);
}]);
But if I change ['auth', 'auth:admin'] to ['auth:admin','auth'] it is working for admin but not for user. So it seems that only the first element of my middleware in array is being recognized. Does anybody have any idea why my multiple middlewares are working seperate but not together? Any help is appreciated
If you are trying to allow multiple 'guards' to be checked for a route you can pass multiple guards as parameters to the Authenticate middleware, auth.
auth:web,admin (assuming web is your default guard).
This will try to resolve a user (Authenticatable) from each guard passed in. If any guard returns a user (Authenticatable) you pass through authenticated. If not you are a guest.
If you set the middleware auth and auth:admin those are 2 separate 'middleware' in the stack that are unrelated.
Route::get('/information', ['middleware' => ['auth', 'auth:admin'],function () {
return view('app', ['data' => ['auth' => Auth::check()]]);
}]);
in this code. ['auth', 'auth:admin'] that's mean you need to login default guard and admin guard. if you need only login admin guard, ['auth:admin']
When I start thinking grouping my routes and check the documentation. I lost there. There are too many things like prefix, middleware etc.
What is the best way to group routes?
Route::group(['middleware' => 'admin'], function () {});
Route::group(['prefix' => 'admin'], function () {});
Route::group(['namespace' => 'admin'], function () {})
Which approach is best? And why? When to use what approach?
Wait. Prefix and middleware are two different things
prefix is a way to Prefix your routes and avoid unnecessary typing e.g:
Route::get('post/all','Controller#post');
Route::get('post/user','Controller#post');
This can be grouped using prefix post
Route::group(['prefix' => 'post'], function(){
Route::get('all','Controller#post');
Route::get('user','Controller#post');
})
In the other hand, Middleware :
Middleware provide a convenient mechanism for filtering HTTP requests entering your application. For example, Laravel includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to the login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.
For example using last example now i want the users to be authenticated in my post routes. I can apply a middleware to this group like this:
Route::group(['prefix' => 'post', 'middleware' => ['auth']], function(){
Route::get('all','Controller#post');
Route::get('user','Controller#post');
})
You should check the docs to get more informed.
https://laravel.com/docs/5.5/middleware
https://laravel.com/docs/5.5/routing#route-groups
Both are different But to use both at the same time Best technique for grouping route middleware and prefix your route avoid unnecessary typing
Route::group(['prefix' => 'admin','middleware' => ['auth:admin']], function() {
Route::get('dashboard','AdminController#dashboard');
});
It may not be related to the current question, but if anyone is wondering how to use grouping prefix and middleware as well as controller in a scenario where you need auth check and then need a prefix to avoid repeat typing for the specific controller group, you may try the following way.
Route::middleware(['auth', 'verified'])
->controller(\App\Http\Controllers\AdminController::class)
->prefix('dashboard')->group(function() {
Route::get('/', 'adminIndex')->name('admin.index');
});
Or,
Route::group(['middleware' => ['auth', 'verified'], 'prefix' => 'dashboard'], function () {
Route::controller(\App\Http\Controllers\AdminController::class)->group(function (){
Route::get('/', 'adminIndex')->name('admin.index');
});
});
I made the files for authentication using the command
php artisan make:auth
I've read on the internet that register, login, as well as logout should work properly, but localhost:8080/logout doesn't work, and I don't know why.
I also read something about modifying AuthController in app, but I do not have that file.
I tried to do it by hand, which means I created a middleware LogoutRedirect:
public function handle($request, Closure $next)
{
return redirect(pages.logout);
}
In the routes I added
use App\Http\Middleware\LogoutRedirect;
Route::get('logout', function()
{
return view('pages.logout');
})->middleware(LogoutRedirect::class);
And logout.blade.php looks like
{{ Auth::logout() }}
I get the error (when trying to access localhost:8080/logout)
Use of undefined constant pages - assumed 'pages'
What could I do about it?
EDIT
I tried another approach (but with no better results):
renamed the route which redirects to '/' to 'home'
made a LogoutController in app/http/Controllers/Auth
namespace App\Http\Controllers;
use [...]
class LogoutController extends Controller
{
public function logout() {
Auth::logout();
return Redirect::route('home');
}
}
made the route
Route::post('logout', array(
'as' => 'account-sign-out',
'uses' => 'Auth\LogoutController#logout'
));
The error I get is
MethodNotAllowedHttpException in RouteCollection.php line 233:
That's the same error I get when I try to use the default logout defined in auth
You are trying to access the logout page with GET. But this doesn't work because your logout route is a post route.
Change
Route::post('logout', array(
'as' => 'account-sign-out',
'uses' => 'Auth\LogoutController#logout'
));
by
Route::get('logout', [
'as' => 'account-sign-out',
'uses' => 'Auth\LogoutController#logout'
]);
When you go to the /logout route with the method GET(The default when you go to a page) it should work.
I am trying to implement a JWT library for an API I am working on and I want to be able to wrap my entire API route group in token checks with a small number of exceptions. The problem I am having is not specific to JWT.
In a controller constructor, when I apply the middleware, I am able to use this syntax to apply jwt.auth to the entire controller and exclude the 'authenticate' endpoint.
public function __construct()
{
// Apply the jwt.auth middleware to all methods in this controller
// except for the authenticate method. We don't want to prevent
// the user from retrieving their token if they don't already have it
$this->middleware('jwt.auth', ['except' => ['authenticate']]);
}
When I attempt to do the same thing in my route group I cannot get the 'exception' array to pass correctly. This causes the authenticate method to require a token (which it can't require because it is the endpoint to RETRIEVE the token).
Route::group(['prefix' => 'api', 'middleware' => 'jwt.auth', 'except' => ['authenticate']], function()
{
Route::resource('authenticate', 'AuthenticateController', ['only' => ['index']]);
Route::post('authenticate', 'AuthenticateController#authenticate');
});
I have a feeling this is a syntax issue, but I cannot find anyone else asking this question and the parser doesn't choke on it, it just doesn't work. Any help would be much appreciated!
I took a brief look in laravel/framework and I didn't see support for this. I would suggest using nested Route::group's something like the following.
Route::group(['prefix' => 'api'], function() {
// Not explicitly behind a middleware
// However a controller could still have a middleware injected.
Route::controller('Auth/AuthController');
// Authenticated Routes
Route::group(['middleware' => 'auth'], function() {
Route::get('secret', 'SecretsController#index');
});
});