I am new in learning laravel. Currently I have been stuck in the Laravel Policy,could you please kindly help with directing me how to add policy to my project?
I would like to make just only the Administrator User be able to see the 'Administration Dashboard' by using Laravel Policies Rules but failed. Actually every registered user is able to see that entrance(just like the attached picture showing below).
The user name is uu#gmail.com and the password is uuuuuu.
Please go to my testing website http://lookoko.com/ and log with the user name and password you will see that Administration Dashboard list in the drop-down lists.
To create a new middleware, use the make:middleware Artisan command:
php artisan make:middleware AdminMiddleware
This command will place a new AdminMiddleware class within your app/Http/Middleware directory. In this middleware, we will only allow access to the route if the logged-in user is admin. Otherwise, we will redirect the users back to the home URI.
<?php
namespace App\Http\Middleware;
use Closure;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (! auth()->user()->is_admin) {
return redirect()->route('home');
}
return $next($request);
}
}
Here I am assumming you have a column in user table named is_admin
Registering Middleware
You should assign the middleware a key in your app/Http/Kernel.php file. By default, the $routeMiddleware property of this class contains entries for the middleware included with Laravel. To add your own, simply append it to this list and assign it a key of your choosing. For example:
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
...
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'admin' => \App\Http\Middleware\AdminMiddleware::class,
];
Once the middleware has been defined in the HTTP kernel, you may use the group method to assign middleware to group of routes:
Route::group(['middleware' => ['admin']], function () {
// all your admin routes comes here
});
Docs
Related
Is there any way to limit users in my project for number of posts. For example, I want my users can create a maximum 10 posts each one. So one user has 10 posts? Is it something with hasMany or something else? Please help find a solution. Thank you
By definition
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.
To prevent user from adding more than 10 posts you need to create a middleware to protect your posts/create route
To create a new middleware, use the make:middleware Artisan command:
php artisan make:middleware CheckUserPostsNumber
This command will place a new CheckUserPostsNumber class within your app/Http/Middleware directory. In this middleware, we will only allow access to the posts/create route if the user posts number < than 10. Otherwise, you will redirect the user back to the home URI:
<?php
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class CheckUserPostsNumber
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (Auth::user()->posts->count() >= 10) {
return redirect('home');
}
return $next($request);
}
}
Assigning Middleware To Routes
you would like to assign middleware to specific routes, you should first assign the middleware a key in your app/Http/Kernel.php file. By default, the $routeMiddleware property of this class contains entries for the middleware included with Laravel. To add your own, append it to this list and assign it a key of your choosing:
// Within App\Http\Kernel Class...
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
//...
'checkUserPostsNumber' => 'App\Http\Middleware\checkUserPostsNumber'
];
Once the middleware has been defined in the HTTP kernel, you may use the middleware method to assign middleware to a route:
Route::get('posts/create', function () {
//
})->middleware('auth', 'checkUserPostsNumber');
Docs
if ($user->posts->count() >= 10) {
//
}
I am new to laravel and voyager
I have one question about voyager. The thing is .. I want to let user do CRUD only on the records created by him/her, so records of other users won't be accessible to him/her but can do add-edit-delete ONLY on his records. How can I archive this in voyager ? The default permissions are working on all records, those does not filter user specific records :(
Landlord should work perfectly for this.
Landlord will apply a global scope to Eloquent that filters records automatically. It does this at a level lower than Voyager in the stack, meaning you won't need any extra configuration on the Voyager end of things.
With Landlord you simply add a column to all your CRUD tables that identify ownership of a record, and then you let Landlord know about this.
For example if you go with the column name user_id, you can then scope to the user anywhere (say in your middleware) with a call as simplistic as Landlord::addTenant('user_id', $userIdHere); Here's an example middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use App\User;
use Landlord as LandlordManager;
class Landlord {
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($request->user()) {
LandlordManager::addTenant($request->user());
LandlordManager::applyTenantScopesToDeferredModels();
}
}
}
You then go to App/Http/Kernel.php, find the $routeMiddleware array and add:
'landlord' => \App\Http\Middleware\Landlord::class
Then go to app/routes/web.php and apply this middleware to any single route or route group according to your favourite flavour in the docs https://laravel.com/docs/master/middleware. An example being:
Route::group(['prefix' => 'admin', 'middleware'=>'landlord'], function () {
// routes here
});
I'm not clear with the concept of middleware in Laravel. What does laravel middleware do? Please provide an example if possible.
Middleware is something that is placed between two requests.
Suppose that you need to make sure that when user access to a specific group of routes he/she is authenticated.
There are two option:
Add in every controller the code to check if user is logged in ( in this example we do not consider a parent controller )
Use a middleware
In the first case you should write in each controller the same code.
With the middleware you have a piece of code that you can re-use in multiple section of your application.
Let's suppose that we want to create a Middleware that need to check if the user is logged in:
namespace App\Http\Middleware;
use Closure;
class UserIsLoggedIn
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (!auth()->user()) {
return redirect('home');
}
return $next($request);
}
}
Now with this code we can check our user where we need.
First of all since this is a custom middleware you need to register it in the app/Http/Kernel.php file in the $routeMiddleware property:
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
// ...
'isLoggedIn => \App\Http\Middleware\UserIsLoggedIn::class,
];
Let's assume that you have a group of routes that need to check the user is logged in:
Route::get('admin/profile', function () {
//
})->middleware('isLoggedIn');
Now all the routes in this group will check if the user is logged otherwise he will be redirect to home.
Now assume that you have another controller that need to make sure that the user is logged in, now you can re-use the middleware to do that:
class MyController extend Controller {
function __construct(){
$this->middleware('isLoggedIn');
}
}
So middleware help you to organize the login and re-use pieces of code for specific tasks.
Laravel has a lot of documentation about middleware that you can find here
I wrote some php function in public directory because I have to use external library.
Then I can't retrieve any session data and authentication data from the controller I have tested with below php script
session_start();
var_dump($_SESSION['user']);
I have initial Session data from AdminMiddlware already
It awesome for using it in Resource->view directories but can not in public.
namespace App\Http\Middleware;
use App\User;
use Closure;
use Illuminate\Support\Facades\Auth;
class AdminMiddleware
{
/**
* Handle an incoming request. User must be logged in to do admin check
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = User::find(\Auth::user()->id);
if ((int) $user->is_admin == (int) config('auth.guards.is_admin')) {
$collection = collect(Auth::user());
$thisdata = $collection->toArray();
$request->session()->put('user', $thisdata);
return $next($request);
}
return redirect()->guest('/');
}}
Ok, the simplest way that I can see to get this to work with Laravel is:
(If you haven't done so already) Copy
public/gallery/scripts/filemanager.config.default.json
to
public/gallery/scripts/filemanager.config.json
Then set "fileConnector"(line 25) to "/authenticate-filemanager", e.g
"fileConnector": "/authenticate-filemanager",
This will tell your Filemanager application to load through the route /authenticate-filemanager.
Next, go to public/gallery/connectors/php/application/FmApplication.php and at the bottom change if(!auth()) to if(!auth()->check()) this will tell the application to use the built-in auth in Laravel.
Then you will need to set up the actual route (this is essentially the contents of filemanager.php without the auth() function):
Route::match(['GET', 'POST'], 'authenticate-filemanager', function () {
require_once(public_path('gallery/connectors/php/application/Fm.php'));
require_once(public_path('gallery/connectors/php/application/FmHelper.php'));
$config = [];
$fm = Fm::app()->getInstance($config);
$fm->handleRequest();
});
Because both GET and POST calls are made to the same endpoint match is used. Make sure you don't put this route behind the auth middleware.
Lastly, you just need to to go to app/Http/Middleware/VerifyCsrfToken.php and add 'authenticate-filemanager' to the $except array to disable csrf for the route.
Hope this helps!
Update for RichFilemanger ver. 2.7.6 and Laravel 5.6
I use RichFilemanager in HTML text editor in admin panel. So check for admin user is logged in.
in public/../RichFilemanager/config/filemanager.config.json
"connectorUrl": "/admin/authenticate-filemanager",
in route/web.php
Route::match(['GET', 'POST'], '/admin/authenticate-filemanager', function () {
//Here check is admin or user is authenticated. Can use: auth()->check()
$isAuth = \App\Libraries\Admin\AdminBLL::isAuth();
if(!$isAuth){
return 'Not authenticated';
}
return require_once(public_path('assets/plugins/RichFilemanager/connectors/php/filemanager.php'));
});
As was wrote before by Ross Wilson: Lastly, you just need to to go to app/Http/Middleware/VerifyCsrfToken.php and add 'admin/authenticate-filemanager' to the $except array to disable csrf for the route.
Last one - setup files folder location in public/../RichFilemanager/connectors/php/filemanager.php
$local->setRoot('userfiles/filemanager', true, true);
i have 2 logins pages on my project
1) cms/admin/login
2) cms/users/login
How to redirect if user to user login page
cms/users/login
and if admin call
cms/admin/ redirect to cms/admin/login page
First of all, you don't know if user is user or admin until he logs into your app, so having 2 different routes for same thing is kinda bad. To achieve something similar what you want, you will need to have one cms/login route where user/admin will login and depending on his status (e.g. 1 - user, 2 - admin) you redirect him on cms/user/page or cms/admin/page. To make this you will have to use Middleware which is very good documented in Laravel official documentation.
For example your middleware for all admin pages should look like this
<?php
namespace App\Http\Middleware;
use Closure;
class AdminMiddleware
{
/**
* Run the request filter.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($request->input('status') == 2) {
//2 means its admin and i let him get that admin page
return $next($request);
}
//he is not admin so i redirect him back
return Redirect::back();
}
}
In Kernel.php you add middleware alias
protected $routeMiddleware = [
'admin' => \App\Http\Middleware\AdminMiddleware::class,
];
And in routes.php you assign middleware to that routes
Route::get('/cms/admin/page', ['middleware' => 'admin', 'uses'=>'Controller#method']);
Hope it helps