欢迎各位兄弟 发布技术文章
这里的技术是共享的
所以我设置了我的数据库的角色和user_role和php工匠修补程序,我可以已经建立连接。
现在在我的用户模型我想添加的功能isAdmin,但我需要一些帮助,我需要如何写这个。
public function isAdmin() {
return $this->hasRole('Admin'); // ?? something like this! should return true or false
}
如果我得到这个工作,我应该可以在我的模板中使用:
@if ( $user->isAdmin() )
<p>Yay! I'm Admin! :P</p>
@endif
那么下一步就是创建一个中间件来保护某些控制器的方法。当我还远的时候可能再来一次
我已经提出了一些线索,每次我在几分钟内得到很好的帮助!大感谢大家!
我认为解决角色和可能的权限的最好办法是使用一个包。例如看我的 - https://github.com/romanbican/roles
如果你不想使用这个软件包,看看代码(src / bican / Roles / HasRole.php),我想你会发现你的问题的答案。
谢谢@romanbican!
在我考虑使用包之前,我真的想自己做这件事情。否则我永远不会在它的顶部。
所以我没有这么远 - “hasRole”是L5的一部分吗?我需要得到角色的名字,虽然在这种情况下是“Admin”
public function isAdmin() {
return $this->hasRole->name('Admin');
}
好吧,这更复杂了。首先,您需要设置角色方法来获取属于用户的所有角色。用户模型添加:
public function roles()
{
return $this->belongsToMany('App\Role');
}
这意味着您还需要创建角色模型。
然后你可以添加到用户模型:
public function isAdmin()
{
foreach ($this->roles()->get() as $role)
{
if ($role->name == 'Admin')
{
return true;
}
}
return false;
}
这只是一个例子,但它应该有效。但这不是理想的。
这个更好:
public function is($roleName)
{
foreach ($this->roles()->get() as $role)
{
if ($role->name == $roleName)
{
return true;
}
}
return false;
}
Role.php
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model {
protected $fillable = [
'name'
];
/**
* A role can have many users.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function users() {
return $this->belongsToMany('App\User');
}
}
user.php的
<?php namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['name', 'email', 'password'];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = ['password', 'remember_token'];
/**
* A user can have many articles.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function articles() {
return $this->hasMany('App\Article');
}
/**
* A user can have many roles.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function roles() {
return $this->belongsToMany('App\Role')->withTimestamps();
}
/**
* Check if user has admin role.
*
* @return mixed
*/
public function isAdmin() {
return ??; //what i am looking for!
}
}
我上面的答案会回答你。
不错哦!!!男人你们真棒!再次感谢您的帮助!
我会确保测试你的包@romanbican!
@romanbican我真的很喜欢你的角色包。有没有办法使用中间件来回应请求?
例如 - 如果用户没有具体的角色或没有权限 - 在中间件中执行某些操作,那么我们的控制器可以保持“更干净”?
@tonicperic嗯,你可以创建自己的中间件,然后检查用户是否是例如管理员。这很容易。
这应该工作:
public function handle($request, Closure $next)
{
if ( ! $this->auth->user()->isAdmin())
{
return new RedirectResponse(url('/home'));
}
return $next($request);
}
@romanbican肯定 如果我真的有很多角色,还是真的很大的权限呢?我必须为每个权限创建一个中间件?
@toniperic将您的ACL注入中间件。例如让我们在您的ACL内说,检查用户是否是管理员
<?php namespace App\Http\Middleware;
use Closure;
use Path\T\Your\ACL;
use Illuminate\Http\RedirectResponse;
use Illuminate\Contracts\Routing\Middleware;
class DashBoard implements Middleware {
/**
* The Acl implementation.
*
* @var Acl
*/
protected $acl;
/**
* Create a new filter instance.
*
* @param Guard $auth
* @return void
*/
public function __construct(ACL $acl)
{
$this->acl = $acl;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($this->acl->is_admin())
{
return new RedirectResponse(url('/dashboard'));
}
return $next($request);
}
}
我认为你不需要为每个权限创建中间件。对于每个角色,是的,我认为这是最好的解决方案。但是,例如,当您提交表单时,您可以检查用户是否具有您的FormRequest内的权限,哪里是授权方法。
检查控制器内的权限真的很糟糕吗?
您可以使用一个中间件,除了一个变量,如权限名称。
还有坏事吗?只有它不工作。但是你把东西放在哪里总是依赖..(恨这个词也是这样)。一般来说,我试图干我的代码,所以如果我反复做完全相同的事情(复制和粘贴),你可能会提取到一个方法或功能,只需调用它。这可能看起来不会干,但是如果使用权利更多可读性取决于您的命名约定。
我试图做同样的事情。我设置了一个Auth :: user() - >是('admin')检查,我已经工作了(按预期返回true或false)。
我现在的问题是,我还有一个与用户ID有外键关系的ServiceOrder雄辩模型。每当我的任何控制器调用ServiceOrder :: get()时,我只想返回属于该用户的ServiceOrders,除非User是管理员,在这种情况下显示所有ServiceOrders。
我知道我可以在我的模型中设置一个查询范围方法,只需调用ServiceOrder :: user($ id) - > get()...但是,我宁愿能够安全地调用ServiceOrder :: get()并具有中间件检查管理员权限,并在必要时自动应用查询范围。这可能使用中间件吗?
Role.php
class Role extends Model
{
// fields that are available for us to use
protected $fillable = ['name'];
}
user.php的
/*
* The user belongs to a role (specified in db)
*/
public function role() {
return $this->belongsTo('App\Role');
}
/*
* Function to check if the user is admin
*/
public function isAdmin() {
if($this->role->name == 'Administrator') {
return true;
}
return false;
}
角色表
class CreateRolesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('roles');
}
中间件
use Closure;
use Illuminate\Support\Facades\Auth;
class IsAdmin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$user = Auth::user();
if(!$user->isAdmin()) {
return redirect('/'); //or via ->intended('/destination')
}
// else
return $next($request);
}
}
来自 https://laracasts.com/discuss/channels/general-discussion/check-if-user-has-admin-role