我已经在互联网上浏览了一段时间,但找不到我的问题的答案,这就是为什么我在这里问这个问题。
我想验证用户的登录身份,但这必须使用两个单独表中的信息来完成。
我要向控制器发送值:徽章和密码 我正在通过
访问它们$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。
答案 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
列始终存在。您可以对其进行更改,以便该帐户也始终包含某些其他列,但是目前,它应该可以正常工作。
在聊天中,在这种情况下,我们一直在讨论login
或loginById
与manual 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。