I have Laravel passport installed on my dev environment. I noticed that no matter if I am logged in or not my api routes work. AN example of one of my routes is
Route::get('/users', function () {
return factory('App\User', 10)->make();
});
Shouldn't it automatically be authenticated with the api middle ware since it is in the api routes?
You should try this:
Route::group(['middleware' => 'auth:api'], function() {
Route::get('/users', function () {
return factory('App\User', 10)->make();
});
});
But for protect your routes not need to use an middleware declared after the route registered?
https://laravel.com/docs/5.5/passport#protecting-routes
I.e:
Route::get('/users', function () {
return factory('App\User', 10)->make()})->middleware('auth:api');
For using authenticated, you should modify your route as follows
Route::get('/users', function () {
return factory('App\User', 10)->make();
})->middleware('auth');
Moreover, please revise file config/auth.php if you did not use a default User class
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\{your User class name}::class,
],
You may need to add the bindings in your /app/Http/Kernel.php
https://laravel.com/docs/5.6/passport#via-middleware
Example:
protected $middlewareGroups = [
'web' => [
...
],
'api' => [
'throttle:60,1',
'bindings',
'auth:api',
],
];
And scopes if you want to use token scoping:
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
Full file example:
https://github.com/jeremykenedy/laravel-passport/blob/master/app/Http/Kernel.php
Related
I need to authenticate my web routes and I decided to use this middleware:
Route::group(['middleware' => ['auth:api']], function () {
Route::get('test', 'MainController#home');
Route::get('test1', 'MainController#home1');
});
I edited config/auth.php file to use my guard:
....
'guards' => [
'web' => [
'driver' => 'oauth2',
'provider' => 'users',
],
'api' => [
'driver' => 'oauth2',
'provider' => 'users',
'hash' => false,
],
],
...
I defined oauth2 in the AuthServiceProvider file like this:
Auth::extend('oauth2', function ($app, $name, array $config) {
// Return an instance of Illuminate\Contracts\Auth\Guard ...
return new OAuth2Guard(app(TokenUserProvider::class), $app->make('request'));
});
This code works well. The auth:api middleware is executed and the user is checked.
Now since I need the sessions I wanted to use auth:web middleware, with the same exact code. But If I use it the user is nomore authenticated and he is redirected to the login page.
I do not know why. Both web and api guards use the same driver.
Laravel provide separate file for API routes routes/api.php you can separate web and api routes routes. all API routes will be prefixed with "api". After separating routes just include 'web' middle-ware
I am working on a project with multiple authentication that has admins, students and teachers as three levels of authentication. I have changed default authenticable user model to student and added two more authenticable models that have their own logins.
I have the CourseController as follows:
use App\Course;
use App\Invoice;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class CourseController extends Controller
{
public function __construct()
{
$this->middleware('auth', ['only' => ['index']]);
$this->middleware('auth:teacher', ['only' => ['index']]);
$this->middleware('auth:admin', ['only' => ['index', 'create', 'store', 'edit', 'update', 'delete', 'search', 'destroy']]);
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$data = Course::get();
if (Auth::user()->role == 'admin') {
return view('admin.course.index', compact('data'));
} elseif (Auth::user()->role == 'student') {
return view('student.course.index', compact('data'));
} elseif (Auth::user()->role == 'teacher') {
return view('teacher.course.index', compact('data'));
}
}
}
config/auth.php as follows:(default guard is student)
'defaults' => [
'guard' => 'web',
'passwords' => 'students',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'students',
],
'api' => [
'driver' => 'token',
'provider' => 'students',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'admin-api' => [
'driver' => 'token',
'provider' => 'admins',
],
'teacher' => [
'driver' => 'session',
'provider' => 'teachers',
],
'teacher-api' => [
'driver' => 'token',
'provider' => 'teachers',
],
],
My problem:
I want CourseController#index to be accessible for all three guards and pass the $data to their respective view. How would I modify the CourseController so that I can achieve this?? Please help
If you have any other ideas you can suggest me that too...
I think it's better to do it via route.
For student guard:
Route::group(['middleware' => ['auth']], function () {
Route::get('student.course.index', 'CourseController#index');
});
For teacher guard:
Route::group(['middleware' => ['auth:teacher']], function () {
Route::get('teacher.course.index', 'CourseController#index');
});
For admin guard:
Route::group(['middleware' => ['auth:admin']], function () {
Route::get('admin.course.index', 'CourseController#index');
//other routes
});
Thanks for the awesome submission! I ran into this problem myself a little while back and realized that doing things in just middleware was not the way to go.
I found that using Gates and Policies where the best route to take. So basically what this means is, each User has a Role, that Role has a Permission, and you are able to use the Blade #can directive to restrict access to certain parts of your site.
You can also use the middleware('can:accessCourse') method chaining in your web.php routes file (HTTP Routes Definition File) to make sure that the route is 'locked down' so to say. If you're using the Route::resource definition, then you can add the line $this->authorize('course.index'); to your index public function.
Using the constructor on your controller is great, but you should only use one middleware for that. I.E. $this->middleware('auth:admin'); Then once that person has 'admin' access, you can check to see if they have the Role and subsequent Permissions to do whatever it is you want.
Heres a short diagram I drew up showing what's going on in the background and to summarize all the stuff I just said.
https://drive.google.com/file/d/1uAcL7awPdxVai590WNuJFvDM_wIpsuYo/view?usp=sharing
Also BitFumes on Youtube has a tutorial series on how to create Admin Roles, Permissions, Defining Gates, Adding Policies, and using 'can' middleware on your Routes! Thats where I learned from myself! Now, he might be a little hard to understand as English isn't his first language, but he knows his stuff!
This link starts half way through a playlist about making a Blog, and starts with making administrator roles! :P
https://www.youtube.com/watch?v=aY7X5v37Ebk&index=25&list=PLe30vg_FG4OTELVqQgHaMaq2oELjpSWy_
Hope that this answer has helped you and guided you towards finding a solution to your problem!
I use Laravel 5.6.33. I would like the user can have an access to the 'dashboard' page only when he/she has signed In/Up. When I use the 'guest' middleware, the user can't access the page at all and when I use the 'auth' middleware, the user always have an access to the page. What shall I do?
Route::group(['middleware' => ['web']], function (){
Route::get('/dashboard', [
'uses' => 'UserController#getDashboard',
'as' => 'dashboard',
'middleware' => 'auth'
]);
});
I have also added $this->middleware('auth'); in the getDashboard function or in the constructor of the UserController but it doesn't work. What shall I do?
In the Kernel.php the auth address is as follows:
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
If you are using Laravel 5.6 you don't need to wrap your routes with web middleware as long as you put them inside your routes\web.php file. Laravel makes this for you in the RouteServiceProvider.php.
For your purpose the auth middleware should work. Try this instead of what you have:
Route::middleware('auth')->group(function() {
Route::get('/dashboard', [
'uses' => 'UserController#getDashboard',
'as' => 'dashboard'
]);
});
you have to do nothing.
just add the following code.
Route::group(['middleware'=>'auth'],function () {
//you can create the list of the url or the resource here to block the unath users.
Route::resource('brands', 'BrandController');
Route::resource('products', 'ProductController');
});
Or use the construct function on the controller which you want to block.
public function __construct()
{
$this->middleware('auth');
}
it will block all the function on that controller like index, create, store, update, delete. only auth can use those functions.
I have configured passport authentication for my model 'Member'(members table).Access token created perfectly while login.But i could not authenticate after login apis.
i am getting below error
BadMethodCallException.Call to undefined method Illuminate\Database\Query\Builder::getAuthIdentifierName()
i thing you forgot to put auth:api middleware in routes.
please use authentication middleware like
Route::group(array('middleware' => ['auth:api']), function() {
//your routes;
});
Passport by default uses User model and here you are using Member table. Just check if you have included Model class inside the auth.php file inside config folder.
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Member::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
Or try this https://github.com/santigarcor/laratrust/issues/134#issuecomment-300318982
I am using multiple auth in my laravel project and it works fine:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'admins' =>[
'driver' => 'session',
'provider' => 'admins',
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
],
But I have Problem with protecting some of my routes. I want these routes to be accessed by two type of authentication guards. if 'admins' guard user is logged in OR if 'users' guard user is logged in, I want to be able to access the route. now my route is like this:
Route::group(['middleware' =>'auth'], function () {
Route::get('/add/tutorial',[
'uses'=>'AddTutorialController#getAddTutorialIndex',
'as'=>'frontend.add.tutorial'
]);
});
and with this, just users from my 'users' guard can access this route.
I want to access maybe something like this:
Route::group(['middleware' =>['auth' OR 'auth:admins']],...
Is there any way to let both of auth guards access the route?? which kind of middleware group I should use?
If you could add an additional parameter to \app\Http\Middleware\Authenticate.php like:
public function handle($request, Closure $next, $guard = null, $default = false)
{
if($guard && $default) {
// check for specified $guard OR default guard
$authorized = Auth::guard($guard)->guest() || Auth::guard(null)->guest();
} else {
// use specified guard ( or null if non given )
$authorized = Auth::guard($guard)->guest();
}
if ($authorized) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('login');
}
}
return $next($request);
}
With that you can specifiy an additional parameter in a route group :
Route::group(['middleware' => 'auth:admins,true'], function() {
Route::get('/', function () {
dd('inside');
});
});
If you use auth:admins,true then the default guard and the specified guard (admins) would be checked with OR.
If you only use auth the default guard will be used. If you use auth:admins
the admins guard will be used only.
This is just a quick example. You can adjust it to your needs, or even write an own middleware.
i found 3 ways, if you can found useful:-
First Way:-
routes.php
Route::group(['middleware' =>['auth', 'auth:admins']], function () {
Route::get('/add/tutorial',[
'uses'=>'AddTutorialController#getAddTutorialIndex',
'as'=>'frontend.add.tutorial'
]);
});
Second Way:-
routes.php
Route::get('/add/tutorial',[
'uses'=>'AddTutorialController#getAddTutorialIndex',
'as'=>'frontend.add.tutorial'
])->middleware(['auth', 'auth:admins']);
Third Way:-
routes.php
Route::get('/add/tutorial',[
'uses'=>'AddTutorialController#getAddTutorialIndex',
'as'=>'frontend.add.tutorial'
])
yourcontroller.php
class YourController extends Controller{
public function __construct(){
$this->middleware(['auth', 'auth:admins']);
}
}