I have a question.
I have table users.
And in table users I have account_type column.
I need determine if user is standard user, or administrator
How I can do it globally in the application?
Now I do this check in every file or controller:
if(auth()->user()->account_type == 0) { ... } else { ... }
You can use Global Middleware
Create a Middleware, for Example :
...
class PageAccess {
public function handle($request, Closure $next) {
if(auth()->user()->account_type == 0) {
return $next($request);
} else {
return redirect('/');
}
}
}
in app/http/Kernel.php add your Middleware
protected $routeMiddleware = [
....
'page_access' => \App\Http\Middleware\PageAccess::class,
];
You can define a Base Controller and extends the BaseController to your all Contontroller like
Class UserController extends BaseController{
....
}
Look for Laravel Repository Pattern. It will help you.
You can create a middleware to define which user type can use the route.
And you can create a function in your user model to check the account type like this :
public function isAdmin(){
return ($this->account_type == 1);
}
So when you need to check the account type you just have to use
auth()->user()->isAdmin()
Related
I'm developing an application which involves authentication and files acl.
Now I want to write a method on the file model called "userCanAccess" which check if the given user/ the user role is in the file acl.
The code will be something along those lines:
public function userCanAccess($user = null) {
$user = is_null($user) ? auth()->user() : $user;
if($this->acl->users->contains($user)
|| $this->acl->roles->contains($user->role)) {
return true;
}
return false
}
Is it right to place this kind of logic on the model?
Laravel has a neat built-in bit of functionality called Policies.
You'd create a FilePolicy that applies to the File model:
php artisan make:policy FilePolicy --model=File
and in the resulting app/Policies/FilePolicy.php, you'll see some ready-to-edit existing policies, one of which is called view. Put your authorization logic here.
Once you've built that, you can apply the policy in a variety of ways, like controller functions, middleware on your routes, or directly within views using the #can Blade directive.
https://laravel.com/docs/5.8/authorization#authorizing-actions-using-policies
This should work just fine for me, but rather than bombing the model class, I would extract it to the trait.
You can make roles and permissions tables
User model:
public function roles()
{
return $this->belongsToMany(Role::class);
}
Role model:
public function users()
{
return $this->belongsToMany(User::class);
}
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
Permission model:
public function roles()
{
return $this->belongsToMany(Role::class);
}
then in app/Providers/AuthServiceProvider you can make Gate like this:
public function boot()
{
$this->registerPolicies();
foreach ($this->getPermissions() as $permission) {
Gate::define($permission->name,function($user) use($permission){
return $user->hasRole($permission->roles);
});
}
}
private function getPermissions(){
return Permission::with('roles')->get();
}
at the end you can use ACL everywhere you want by just write Gate name like:show-comments or access-files or ....
I want to fetch data only when the auth is an admin.
The User controller:
public function index()
{
if (auth::user()->type == 'admin') {
return User::where('type','!=','admin')->latest()->paginate(100);
}
}
I got an error:
Trying to get property 'type' of non-object.
This code:
if (auth::user()->type == 'admin') {
should be.
if (auth()->check() && auth()->user()->type == 'admin') {
Explanation:
auth()->check() -- makes sure there is a user logged in.
&& -- stops after the first check if it is false
auth()->user()->type -- gets the type attribute from the user
If you are using role based authentication then You can check user role by creating the function in user model
USER MODEL
public function isAdministrator()
{
return $this->hasRole('admin');
}
USER CONTROLLER
class userController
{
public function index()
{
if(Auth::user()->isAdministrator())
{
# code...
}
}
Try this: Create middleware and pass route through middleware, it will work
public function handle($request, Closure $next)
{
if (auth()->user() && auth()->user()->type != 'admin')
{
return redirect('/unauthorized');
}
return $next($request);
}
You can use the method hasRole to check whether the role is admin or not.
public function index()
{
if (auth::user()->hasRole('admin')) {
return User::latest()->paginate(100);
}
}
i have level column in user table , i wanna redirect to their panel in laravel after login but i dont know where check and redirect user???
i try to login safty
Can this code be correct?
protected function authenticated(Request $request, $user)
{
if(auth()->user()->isAdmin())
{
return redirect('/admin/panel');
} elseif(auth()->user()->isWriter())
{
return redirect('/writer/panel');
}
return redirect('/user/panel');
}
Overwrite redirectPath() method to your LoginController.
class LoginController extends Controller
{
use AuthenticatesUsers;
public function redirectPath()
{
if (auth()->user()->isAdmin())
{
return '/admin/panel';
}
elseif (auth()->user()->isWriter())
{
return '/writer/panel';
}
return '/user/panel';
}
}
In LoginController that uses Illuminate\Foundation\Auth\AuthenticatesUsers trait for authentication you must override the redirectTo() method and write your own logic. so you must something like this code:
protected function redirectTo(){
$user = User::whereId(Auth::id())->first();
if(isset($user)){
if($user->role == 'admin'){
return '/admin/panel'; //path to admin panel
}elseif($user->role == 'writer'){
return '/writer/panle'; //path to writer panel
}
}
return '/';
}
I am passing a value in shared view by taking value from table. I need to know user ID for the purpose but Auth::check() returns false. How do I do it? Below is code:
public function boot()
{
$basket_count = 0;
if (Auth::check()) { //always false
$loggedin_user_id = Auth::user()->id;
$basket_count = Cart::getBasketCount();
}
view()->share('basket_count', $basket_count);
}
OK turns out that ServiceProviders are not place for such things. The best thing is a Middleware. So if you want to call Auth, create middleware and pass value to views.
public function handle($request, Closure $next)
{
$basket_count = 0;
if ($this->auth) { //always false
$loggedin_user_id = $this->auth->user()->id;
$basket_count = Cart::getBasketCount($loggedin_user_id);
}
view()->share('basket_count', $basket_count);
return $next($request);
}
You can use authentication directly in the controller file. Adding it in the middleware is a cleaner way of doing the authentication.
For eg. In CategoriesController.php
...
class CategoryController extends Controller {
/**
* CategoryController constructor.
*/
public function __construct()
{
$this->middleware('auth');
}
...
If you want to have a look at a complete example
http://deepdivetuts.com/basic-create-edit-update-delete-functionality-laravel-5-3
When updating a user's account, what is the best way to only allow the user itself and the admin to do so?
I use multiauth and the only way I can think of is:
public function update($id)
{
if (Auth::admin()->check() || Auth::user()->get()->id == $id)
{
// Allow update
}
}
Is there a cleaner way to do so?
Where you put this code depends on your architecture.
If it's a simple setup, the model might be the perfect place for it:
class User extends Eloquent implements .... {
protected static function boot($id)
{
static::updating(function($user)
{
return $user->canCurrentUserUpdate();
});
}
protected function canCurrentUserUpdate()
{
return Auth::admin()->check() || Auth::user()->get()->id == $this->id;
}
}