usuarios usuario personalizado modificar control code autenticacion and php laravel laravel-5

php - usuario - modificar login laravel



Laravel 5.1 usuarios, roles y acciones (5)

Eloquent no tiene una relación HasManyThrough en 2 tablas dinámicas.

1. Puede obtener las acciones por perezoso ansioso por cargar los roles y acciones, y luego extraerlos:

$actions = $user->load(''roles.actions'')->roles->pluck(''actions'')->collapse()->unique();

2. Puede verificar la acción directamente en la base de datos, usando una restricción whereHas :

$allowed = $user->roles()->whereHas(''actions'', function ($query) use ($action) { $query->where(''name'', $action); })->exists();

Estoy creando una aplicación que usa Laravel 5.1 con usuarios , roles y acciones .

La configuración de la tabla es así:

usuario

id name 1 John Smith 2 Fred Smith

papel

id name 1 Administrator 2 Customer

role_user

user_id role_id 1 1 2 1

acción

id name description path 1 dashboard ability to access dashboard /admin 2 editAdmin ability to edit admins /admin/users/administrators/{id}/edit

action_role

action_id role_id 1 1 2 1

La tabla de user contiene TODOS los usuarios en el sitio, incluidos los administradores y los clientes.

La tabla de role contiene todas las funciones posibles que un usuario puede tener. Por ejemplo, administrador o cliente .

La tabla role_user es una tabla dinámica que vincula role a user .

La tabla de action enumera todas las acciones posibles (es decir, urls o rutas) en la aplicación.

El action_role es una tabla dinámica que vincula la action al role .

Entonces para resumir:

  • Los usuarios tienen roles
  • Los roles tienen acciones
  • Un usuario puede tener muchos roles
  • Un rol puede tener muchas acciones

Quiero tener una configuración de middleware que compruebe la carga de la página si el usuario tiene permisos para ver la página actual. Para hacer esto, necesito poder acceder a las acciones de un usuario, usando una llamada como esta:

$user->roles()->actions();

¿Cómo configuro mis relaciones elocuentes para admitir este tipo de llamadas?

ACTUALIZAR

Mis relaciones están configuradas así en mis modelos:

Usuario

/** * The roles that belong to the user. * * @return Object */ public function roles() { return $this->belongsToMany(''App/Models/User/Role'')->withTimestamps(); }

Papel

/** * The actions that belong to the role. * * @return Object */ public function actions() { return $this->belongsToMany(''App/Models/User/Action''); } /** * The users that belong to the role. * * @return Object */ public function users() { return $this->belongsToMany(''App/Models/User/User''); }

Acción

/** * The roles that belong to the action. * * @return Object */ public function roles() { return $this->belongsToMany(''App/Models/User/Role''); }


Necesitas una relación HasManyThrough aquí ... Aquí hay algo para que comiences.

A juzgar por sus tablas dadas, veo que tiene una relación uno a muchos con el usuario y los roles. Si bien la acción y los roles también tienen una relación de muchos a muchos.

Pero primero necesita crear modelos para cada entidad (usuario, rol, acción) para seguir la estructura de MVC. Podrías hacer fácilmente estos modelos desde la línea de comando usando el artesano de Laravel con este comando.

php artisan make:model User

Asegúrese de agregar o cambiar columnas en las migraciones recién creadas. Suponiendo que también tiene configuradas sus tablas dinámicas para las 3 tablas, ahora puede agregar las relaciones.

class User extends Model { // protected $table = ''users''; /* * @var table * */ public function action() { return $this->hasManyThrough(''App/Action'', ''App/Role''); } }

Ahora tienes una relación HasManyThrough . Puede consultar de esta manera directamente sin necesidad de incluir el rol.

//this $actions = User::find(1)->action(); //instead of $actions = User::find(1)->role()->action(); //this will return all actions available to a user with id of 1

NOTA : También sugiero que haga que sus roles y modelos de usuario estén en una relación uno a uno.


Para manejar el usuario, los roles de usuario y los permisos de usuario, simplemente puede usar el paquete Toddish .

Hay muchas cosas que este paquete hace por ti. me gusta:

$user->is(''Your Defined Role''); $user->can(''add_user''); $user->level(7);

Para la instalación, solo lea su documentación.


Si bien mencionó que sus modelos Eloquent (y sus relaciones) están configurados, asumo que ya tiene lo siguiente en su aplicación:

Modelo de usuario

class User extends Eloquent { public function roles() { return $this->belongsToMany(''App/Models/Role''); } }

Modelo a seguir

class Role extends Eloquent { public function actions() { return $this->belongsToMany(''App/Models/Action''); } public function users() { return $this->belongsToMany(''App/Models/User''); } }

Modelo de acción

class Action extends Eloquent{ public function roles(){ return $this->belongsToMany(''App/Models/Role''); } }

Teniendo en cuenta lo anterior, no se puede hacer una llamada como la siguiente ya que Laravel asumirá que está haciendo una llamada a un método de creación de consultas o lo que sea [que de hecho no existe]:

$userActions = App/Models/User::find(1)->roles()->actions();

En su lugar, debe usar el método mágico whereHas Laravel para consultar relaciones donde se involucran múltiples relaciones anidadas.

Ahora, con la id del usuario y la action permitida actual [ que de hecho se puede utilizar en su middleware ], se puede determinar si el usuario puede ver la página:

$hasAccess = App/Models/User::whereHas(''roles.actions'', function($q) use ($id, $action){ $q->where(''users.id'', $id); $q->where(''actions.name'', $action); })->get()->toArray(); if($hasAccess){ // or `count($hasAccess) > 0`. The former will work since any number > 0 evaluates to true in PHP //user has access }

Observe el anidamiento de las relaciones con . .

Relación de Existencia en Laravel :

En Laravel, la existencia de una relación entre modelos se determina con los métodos has y whereHas . El método has se usa solo para determinar si existe una relación , por ejemplo, ejecutando App/User::has(''roles'')->get() siempre obtendrás una lista / colección de usuarios que al menos tienen algún rol . Se puede agregar más potencia a esto con whereHas con el que puede agregar cláusulas where a la consulta real.


Hola, así es como resolví esto.

No usé una tabla de acciones. Solo usuarios , roles y la tabla user_role . Después de la solución, paso mi middleware personalizado una matriz de roles a cada ruta que creo como:

Route::get(''insights'',[ ''as''=>''insights'', **''middleware''=>[''access.level''],** **''roles''=>[''admin'',''customer''],** ''uses''=>''CustomersController@index'' ]);

Archivos modificados: aplicación / Http / Controllers / Controller.php middleware personalizado: aplicación CheckAccessLevel / Http / Kernel.php app / Http / routes.php

Controller.php En este archivo, deseé cargar el usuario conectado actual con sus roles y convertirlo en una variable global en todas las vistas como {{currentUser}} y en todos mis controladores como "$ this-> currentUser" . este es el código:

protected $currentUser; public function __construct() { if(isset(Auth::user()->username)){ $this->currentUser = User::with(''roles'')->where([''username'' => Auth::user()->username])->first(); // Share this property with all the views and controllers in your application. view()->share(''currentUser'', $this->currentUser); } }

Middleware personalizado: CheckAccessLevel.php

Aquí en el middleware, recupero la matriz de roles pasada a la ruta y también los roles asignados al usuario actual. Después de obtener estas variables, las cruzo para ver si hay una coincidencia antes de pasar al usuario. revisa el siguiente código:

//if user is not logged in, show them where to login :) if (!Auth::check()) { return redirect()->route(''user::login''); } //Otherwise get the roles for that route $get_route_action = $request->route()->getAction(); $get_route_roles = $get_route_action[''roles'']; //Eager load the user with their list of roles $eager_user = User::with(''roles'')->where([''id''=>$request->user()->id])->first(); $user_roles = $eager_user->roles->pluck(''role_name'')->toArray(); //intersect the users roles with the route roles to see if there is a match foreach ($user_roles as $user_role){ if(in_array($user_role, $get_route_roles)){ return $next($request); } }

Kernel.php aquí, registro mi ruta como "access.level" dentro del grupo de middleware de la ruta

Route.php cada vez que creo una ruta, ¡solo le paso los nombres de roles permitidos y voala! Esto funciona para mi..

Espero que esto ayude.