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



我已经在Internet上浏览了一段时间,我无法找到我的问题的答案,这就是为什么我在这里问它。

我想对用户进行身份验证以登录,但必须使用来自两个单独表的信息来完成。

我将值发送到我的控制器:徽章和密码我正在用

访问它们
$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。

,因为如果正确的帐户,您已经拥有ID,只是帐户与相关用户之间的关系。

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

'providers' => [ 
    'users' => [ 
        'driver' => 'eloquent', 
        'model' => AppModelsAccount::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列。您可以更改它,以便该帐户也始终包含某些其他列,但是目前,这应该按预期工作。


在聊天中,在这种情况下,我们一直在讨论使用loginloginById的手动身份验证优势的主题。可能的解决方案是:

$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!']); 
}

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

此JOIN会自动用帐户ID替换给定的帐户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')

在此处阅读有关全局范围使用的更多信息。

相关内容

最新更新