How to deny access to certain routes / views for users - laravel

I am trying to deny access for users other than the one with id=1 (in my case it's admin) to 'cpanel' (admin panel) view. I was trying to achieve this with ACL, but somehow I think that this is not the most correct way.
This is what I want to do in pseudocode version
if (isAdmin())
renderPage()
else
print "You are not allowed to view this page"
Reading documentation I found this line declared in custom Controller
$this->authorize('update', $post);
where 'update' is an ability defined elsewhere, and the $post seems to always be a model (use App\Post) that I don't know how to implement. I don't think that Laravel's documentation covers how to implement models for authorization.
How can I authorize a view? It's Laravel 5.2

Related

Storing User Roles in Session Laravel

Hello there I am working on a project in Laravel in which i need to assign permission to each user so that i could verify on each blade file or controller function to check whether the current user has the permission to perform this. Moreover, the side nav links are also generated using these permissions dynamically.
I created two tables:
1: User => [ID, Name .....]
2: Permissions => [ID, Name, user_id(fk)]
To solve this problem, i have stored all the permissions of users in session at the time of login. So that i can verify all permissions on each page and generate links fetching from session.
Is that good approach or there is any better solution for this
It would be good if you had share more code but i can see what you are want to archive. Firstly you dont need to store in the Session because you have already a relation between user Object and Permission. Add to your User model this lines of code:
public function permissions() {
return $this->belongsTo(User::class);
}
Then you have access in your blade or controller to the permission. Small example in the controller:
$user = User::find(1);
dd($user->permissions);
// you can write a condition to check if user has Permission etc.
Yes you can store this is the session. But the more better option will be to get the permission through relation object like
user::find(1)->permissions()
Well if you're asking "better solution" ... but I Not sure if it's too late for this information since you're already developing the project. However, I would recommnend this package for your long term management (for both user and dev).
Spatie Laravel-permission package
It has Role based permission and Direct permission design (which is similar to your design). Once you installed the package then role and permission tables are created for you.
Once you created desired roles with permissions, it's easy for you to manage which page to allow for which role and which button show be shown.
You can check roles in your controller for those who can view this page.
In blade, you can check both roles and permission for which button to show or disable.
Hence, your don't need to worry about session settings or session expires. It's better for maintaining and development in future.
The Spatie package has simple syntax and easy to work with.
Installation:
composer require spatie/laravel-permission
Syntax:
Basic usage and syntax
There are plenty information or tutorials out there.

Where to define permissions for every crud action in laravel

I have designed a store with Laravel 6 ,and used laravel-permission 3 for user management. I'd like to restrict every crud action by a definite permission (e.g. add product, delete product).
There is a short description about using wildcard permission in Spatie, but I'm not sure about it. I don't know where is the best place in defining these restrictions.
Here is a route sample for creating and editing product and their middleware (restrictions by permissions).
Route::get('/create','Controller#create')->name('create')->middleware('permission:add product');
Route::post('/store', 'Controller#store')->name('store')->middleware('permission:add product');
Route::get('/{product}/edit', 'Controller#edit')->name('edit')->middleware('permission:edit product');
Route::patch('/{product}/update', 'Controller#update')->name('update')->middleware('permission:edit product');
I suggest that use Laravel’s Model Policies, you can find more information in the link below.
https://docs.spatie.be/laravel-permission/v3/best-practices/using-policies/
Furthermore, You can find an example of implementing a model policy with this Laravel Permissions package in this demo app:
https://github.com/drbyte/spatie-permissions-demo/blob/master/app/Policies/PostPolicy.php

Laravel 5.8 Manual user approval?

I am new to laravel and before asking this question. I have read various other topics regarding this question sadly none of them helped me.
I have laravel 5.8 and use auth which I installed with:
php artisan make:auth
Now I read that I either need to make a middleware or edit the logincontroller. But what I want is the user to be redirected to a custom page that I already made saying they need to wait to be approved.
Could someone point me in the right direction and tell me which files I need to edit to achieve this?
I have already added a BIT column in the database table called is_approved which is auto set to 0.
In your
App/Htpp/Controllers/Auth
you'll find all the logic of authentication and registration of the user. Inside the controllers, you'll see this:
/**
* Where to redirect users after verification.
*
* #var string
*/
protected $redirectTo = '/home';
Last line is what you're looking for, it's pointing the view/route where your user will be redirected after the respective action.
Also, all your generated views when you run the make:auth command will be in
resources/views/auth
if you feel the need to modify them.
Go here. HomeController. Under return view('home'); change it to
if (Auth::user()->is_approved === "1"){
return view('home');
} else {
return view('welcome');
}
Where 'welcome' you can change to your custom page and '1' assumes the user has been approved. Remember to add use Illuminate\Support\Facades\Auth; to the top of that controller. I had that problem and came to read your post. Thought to drop what I did. It works for me
You need to build a user approval system. A common way is store an active state on the users table as a boolean MySQL column. Then check that column if a user tries to login. As for registration you need to write to the users table with an active state of 0 or false. It would be also great to trigger a notification to you the admin that "hey, you need to go approve a new user". It could be handled through Laravel Nova dashboard where ideally you only need to click a button.
It's not built into the Laravel framework but definitely seems like a good use case!

Laravel limiting access to route

I am trying to implement a basic image fetch system for my website. Already created a route that returns me the image.
what concerns me is that i want that route to be only accessible by certain controllers.
Tried to search it and found out passport might be viable option but it's pretty complex for this app. Are there any possible options ?
EDIT:
Sorry for providing insufficient information. I want the route to be accessible only by CONTROLLERS, not by anyone who enters the route url to address bar. Like using it as an api maybe.
There several ways to achieve that, you can use middleware, you can consider using packages like entrust which also require you to have some knowledge about using middleware. or use laravel Auth
create a table add all the routes in that table and then check the allowed route in AppService provider.
$routename = Request::route()->getName();
$allowed_route = AllowedRoutes::where("route","=",$routename)->count();
if($allowed_route == 0)
exit();

Codeigniter: using a custom MY_Controller effectively for user authentication - passing vars to models etc

I am utilizing a custom MY_Controller to authenticate users on my Codeigniter website.
I utilize $this->load->vars($data); such that I can access the users information in views.
My first question is, does $this->load->vars($data); allow access in models, and if so how - i couldn't find any information. If not, how can I get my logged in users username to my models without having to pass it through a controller every time?
Secondly... if the user is not logged in, I redirect them redirect(base_url() . 'account/login');
This works great, except because my account controller also extends MY_Controller, it gets stuck in an infinite redirect loop. I can just not extend the custom controller for this page, but I see no reason why a logged in user should not still be able to look at the login page.. any ideas?
Finally.. if a user is logged in, $user['username'] is defined in my views.
If a user is not logged in, it is not defined.
As such if i have if($user['username']!=''){ within my code, when a user IS logged in, all is fine and the code executes, however when no user is logged in errors pop up as regards an undefined variable being used in an if statement...
Codeigniter being difficult..
What is the work around here?
Many Thanks !!
I agree with Chris about storing user details in the session.
To check if a user is logged in you could write a gatekeeper function and place it in the controllers construct to protect controllers (and therefore the views).
Something like;
function gatekeeper()
{
if (!isset($this->session->item('username')) || !$this->session->item('username'))
{
redirect('/account/login);
}
}
I would consider storing the userdata for the currently logged in user in the session so that you don't need to query it and pass it to the view every time. You can access session data in the controllers, views and models with $this->session->userdata('your_userdata_var_name');.
The reason $user['username'] displays an error is probably because it's being completely removed, not set to an empty string (''), in which case you are trying to access an undefined array key.

Resources