来自用户表的PHP Laravel Auth密码,来自另一个表的ID

时间:2019-05-15 08:48:00

标签: php laravel authentication laravel-5

我已经在互联网上浏览了一段时间,但找不到我的问题的答案,这就是为什么我在这里问这个问题。

我想验证用户的登录身份,但这必须使用两个单独表中的信息来完成。

我要向控制器发送值:徽章和密码 我正在通过

访问它们
$request->badge (note: This is the account id)
$request->password (note: this is the users password)

以前我尝试过以下方法:

public function store(Request $request)
{
    $request->validate([
        'badge' => 'required|int',
        'password' => 'required|string',
    ]);

    $account = Account::select('id', 'user_id')->where('id', $request->badge)->first();
    if(!$account)
        return back()->withInput()->withErrors(['password' => 'Incorrect badge or password!']);
    else
    {
        if(Auth::attempt(['username' => $accounts->user->username, 'password' => $request->password])) 
        {

            return redirect()->route('home');
        }       
        else 
        {
            return back()->withInput()->withErrors(['password' => 'Incorrect badge or password!']);
        }

    }    
}

这将使用户登录,但是当我使用Auth :: id()时,它将返回用户的ID,而不是帐户的ID。

示例:$ request->徽章填充了25个(即帐户ID),用户ID为1。Auth :: id返回1,而不是我想要的25。

我的表格如下所示:

users
----
id
username
email
password

accounts
-----
id
user_id
name

我在帐户和用户之间建立了联系,以将它们链接在一起

public function accounts()
{
    return $this->hasMany(Accounts::class, 'user_id', 'id');
}


public function user()
{
    return $this->belongsTo(User::class, 'id', 'user_id');
}

我希望auth :: id给我25而不是1。

2 个答案:

答案 0 :(得分:1)

由于您已经拥有了正确帐户的ID,因此帐户与相关用户之间只有hasOne关系。

在身份验证配置中,您需要将users提供程序的模型更改为您的实际帐户模型:

'providers' => [ 
    'users' => [ 
        'driver' => 'eloquent', 
        'model' => App\Models\Account::class, 
    ],
],

然后,在帐户模型中,我们添加一个全局范围,该范围始终从相关的用户条目中获取密码,因此auth不会出现问题:

class Account extends Model
{
    protected $table = 'accounts';

    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('withPassword', function ($builder) {
            $builder
                ->join('users', 'accounts.user_id', 'users.id')
                ->select(DB::raw('accounts.*, users.password'));
        });
    }
}

如果您查询帐户,则范围确保password列始终存在。您可以对其进行更改,以便该帐户也始终包含某些其他列,但是目前,它应该可以正常工作。


在聊天中,在这种情况下,我们一直在讨论loginloginByIdmanual authentication的优势。一个可能的解决方案是这样:

$account = Account::select(
    'accounts.id',
    DB::raw('(SELECT `password` FROM users WHERE accounts.user_id = users.id) AS `password`'))
) 
    ->where('accounts.id', $request->badge)
    ->first();

if ($account) { 
    if (Hash::check($request->password, $account->password)) { 
        Auth::loginUsingId($account->id);

        return redirect()->route('home'); 
    } else { 
        return back()->withInput()->withErrors(['password' => 'Incorrect badge or password!']); 
    } 
} else { 
    return back()->withInput()->withErrors(['password' => 'Incorrect badge or password!']); 
}

答案 1 :(得分:0)

在这里我可能走错了路,但是您可以做的是将全局范围应用于Users模型,该模型在每次查询用户时都会自动加入accounts表。

在给定联接如何工作的情况下,此联接会自动用帐户ID替换user_id,但您可能必须摆弄raw select才能获得所需的值。

class User extends Model
{
    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('account', function (Builder $builder) {
            $builder->join('accounts', 'users.id', ''accounts.user_id');
        });
    }
}

要从任何查询中删除范围,只需使用User::withoutGlobalScope('account')

在此处详细了解usage of global scopes