laravel 在角色上使用 eloquent 驱动程序进行身份验证

Posted

技术标签:

【中文标题】laravel 在角色上使用 eloquent 驱动程序进行身份验证【英文标题】:laravel authentication with eloquent driver on roles 【发布时间】:2015-03-03 21:46:39 【问题描述】:

我正在尝试在我的 Laravel 应用程序中对用户进行身份验证。

我遇到以下问题:

在 auth.php 中使用驱动程序 database:我可以使用 auth::attempt() 登录,并且 auth::check 正在工作,但我无法验证登录的用户是否有特定的角色。 在 auth.php 中使用驱动程序 eloquent:我可以使用 auth::attempt() 登录,但 auth::check 不起作用。但是,我可以检查登录用户的角色。

编辑(问题):如何解决此问题,以便仅使用一个驱动程序,我可以进行完整的身份验证和角色检查?

迁移表:

Schema::create('users', function ($table) 
        $table->increments('id');
        $table->integer('group_id')->unsigned();
        $table->string('name', 64);
        $table->string('email', 64)->unique();
        $table->string('username', 64)->unique();
        $table->string('phone', 13);
        $table->string('address', 64);
        $table->boolean('isresponsible');
        $table->string('password', 64);
        $table->rememberToken()->nullable();
    );
Schema::create('roles', function ($table) 
        $table->increments('id');
        $table->string('name');
    );

Schema::create('users_roles', function ($table) 
            $table->integer('user_id')->unsigned();
            $table->integer('role_id')->unsigned();
        
    );
Schema::table('users_roles', function($table)
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        $table->foreign('role_id')->references('id')->on('roles');
    );

模型类用户

<?php
use Illuminate\Auth\UserTrait;`
use Illuminate\Auth\UserInterface;`
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;

class User extends Eloquent implements UserInterface, RemindableInterface 


use UserTrait, RemindableTrait;

/**
 * The database table used by the model.
 *
 * @var string
 */
protected $table = 'users';
public $timestamps = false;

public static $rules = ['name' => 'required', 'group_id' => 'required', 'email' => 'required', 'phone' => 'required'];
protected $fillable = ['name', 'group_id', 'email', 'phone', 'address', 'isresponsible', 'password'];

/**
 * The attributes excluded from the model's JSON form.
 *
 * @var array
 */
protected $hidden = array('password', 'remember_token');

public function group()

    return $this->belongsTo('Group');


public function userroles()
    return $this->hasMany('Userrole');


public function roles()

    return $this->belongsToMany('Role', 'users_roles');


public function hasRole($check)

    dd($this->roles->toArray());
    return in_array($check, array_fetch($this->roles->toArray(), 'name'));


public function setBasicPassword($id)
    $user = User::find($id);
    $user->password = Hash::make('changeme');
    $user->save();


public function isValid()

    $validation = Validator::make($this->attributes, static::$rules);
    if ($validation->passes()) return true;
    $this->messages = $validation->messages();
    return false;



/**
 * Get the e-mail address where password reminders are sent.
 *
 * @return string
 */
public function getReminderEmail()

    // TODO: Implement getReminderEmail() method.


/**
 * Get the unique identifier for the user.
 *
 * @return mixed
 */
public function getAuthIdentifier()

    return $this->email;


/**
 * Get the password for the user.
 *
 * @return string
 */
public function getAuthPassword()

    return $this->password;


/**
 * Get the token value for the "remember me" session.
 *
 * @return string
 */
public function getRememberToken()

    return $this->remember_token;


public function setRememberToken($value)

    $this->remember_token = $value;


public function getRememberTokenName()

    return 'remember_token';


模型类角色

class Role extends Eloquent


protected $table = 'roles';
public $timestamps = false;

public static $rules = ['role_id' => 'required', 'name' => 'required'];
protected $fillable = ['name'];

/**
 * Get users with a certain role
 */
public function userroles()

    return $this->belongsToMany('User', 'users_roles');


HomeController认证功能

 public function authenticate()
    $rules = array(
        'email'    => 'required|email',
        'password' => 'required|alphaNum|min:3'
    );
    $validator = Validator::make(Input::all(), $rules);
    if ($validator->fails()) 
        return Redirect::to('login')
            ->withErrors($validator)
            ->withInput(Input::except('password'));
     else 
        $userdata = array(
            'email' => Input::get('email'),
            'password' => Input::get('password')
        );
        if (Auth::attempt($userdata, true)) 
            return Redirect::action('HomeController@index');

         else 
            return Redirect::action('HomeController@login')->withInput();
        
    

使用数据库驱动程序 - auth:attempt() 和 auth::check 正在工作

$this->beforeFilter('admin', ['only' => ['index']]); //filter in controller
//filter in filters;php
Route::filter('admin', function()

if(!Auth::check()) return Redirect::action('HomeController@index');
if(!Auth::user()->hasRole('admin')) return View::make('errors.401');
);

这会因“调用未定义的方法 Illuminate\Auth\GenericUser::hasRole()”而失败

EDIT database 驱动程序返回一个 GenericUser 对象,我需要自己的 User 对象。不知道哪里可以改。

解决方法:我宁愿不使用这个,丑陋的代码和过滤器(或视图)不需要这样做

Route::filter('admin', function()

    if(!Auth::check()) return Redirect::action('HomeController@index');
    $user = User::find((Auth::user()->id));
    if(!$user->hasRole('admin')) return View::make('errors.401');
);

使用 ELOQUENT 驱动程序

auth::attempt() 成功 auth::check() 失败 过滤器没有错误

【问题讨论】:

您是否只尝试了Auth::attempt($userdata) 而没有记住选项? 是的,结果是一样的 Auth::id() 有效吗? (使用 Eloquent 时) 返回用户名/电子邮件地址 啊啊啊!!现在写一个答案:) 【参考方案1】:

问题在于您对getAuthIdentifier() 的实现。此方法实际上应该返回表的主键,而不是用于登录的用户名。

所以你的应该是这样的:

public function getAuthIdentifier()
    return $this->id;

或者实际上,我建议您进一步清理模型,因为所有 getSomeAuthStuff 方法都在这两个特征中实现。

使用default model on github 作为基础并添加所有自定义代码(角色方法、规则等)

背景资料

getAuthIdentifier() 返回的值将存储在会话中。 之后使用check() 时,retrieveById 将在UserProvider 上调用。 EloquentUserProvider 这样做:

public function retrieveById($identifier)

    return $this->createModel()->newQuery()->find($identifier);

它使用find(),通过它的主键搜索模型(通常是id

【讨论】:

以上是关于laravel 在角色上使用 eloquent 驱动程序进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent重音角色问题

Laravel 5 Eloquent在多个级别上向JSON添加关系

Laravel 5.3 Eloquent 关系 - 用户、角色、页面和权限

Laravel Eloquent - 返回具有特定角色的用户(多对多关系)

通过 eloquent 具有子项和权限的 Laravel 菜单

Laravel 混合获取 Eloquent 急切加载嵌套多个模型