更改 SQL 对 Auth 的查询,Laravel 5.1
Change SQL query on Auth, Laravel 5.1
登录时,查询失败,因为"email"不在"usuario",在"persona"
Unknown column 'email' in 'where clause' (SQL: select * from `usuario` where `email` = admin@localhost limit 1)
这不是更改数据库模型的解决方案,因为并非所有 "persona" 都是 "usuario",但所有 "usuario" 都是 "persona"。
尝试设置关系:
class Persona extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{....}
public function usuario()
{
return $this->hasOne('App\Usuario');
}
//----------------------------------------------------//
class Usuario extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
{....}
public function persona()
{
return $this->hasOne('App\Persona');
}
两个表具有相同的键。
但是查询没有改变,我想也许 Laravel 可以在某处创建一个 "INNER JOIN",不知道 Laravel 是否可以自动完成,所以我尝试了更改查询但不知道具体位置。
我想过这样的解决方案,但看起来太容易了,不知道是否是个好方法=/
- 从 post
获取 EMAIL 和 PASSWD
- 使用SQL
从BD获取ID、EMAIL和PASSWD
- 如果[EMAIL 和 PASSWD 匹配] Auth::loginUsingId(ID); [ELSE] Return 有错误。
据我所知,Auth::loginUsingId(ID);就像一个成功的 Auth::attempt()...但是有了这个解决方案,我需要知道如何分别实现以后的 Throttles 和 "remember" 选项...欢迎所有想法:D
我找到了一个解决方案:更改了 postLogin() 但在 AuthController 内部,因此我可以保留 Throttles 和 Remember 功能,并且核心仍然不变,如果我可以帮助其他人,请使用以下代码:
//------------------------------------
// Auth\AuthController.php
//------------------------------------
protected function postLogin(Request $request)
{
$this->validate($request, [
$this->loginUsername() => 'required', 'password' => 'required',
]);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $this->hasTooManyLoginAttempts($request)) {
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
//Here's the custom SQL, so you can retrieve a "user" and "pass" from anywhere in the DB
$usuario = \DB::select('
SELECT
persona.nombre,
usuario.password
FROM
persona
INNER JOIN
usuario ON persona.id_persona = usuario.id_persona
WHERE
persona.email = ?
LIMIT 1', array($credentials['email']));
// Instead of:
// if (Auth::attempt($credentials, $request->has('remember'))) {
if ($usuario && Hash::check($credentials['password'], $usuario[0]->password)) {
Auth::loginUsingId($usuario[0]->id_persona, $request->has('remember'));
// Put any custom data you need for the user/session
Session::put('nombre', $usuario[0]->nombre);
return $this->handleUserWasAuthenticated($request, $throttles);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
if ($throttles) {
$this->incrementLoginAttempts($request);
}
return redirect($this->loginPath())
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors([
$this->loginUsername() => $this->getFailedLoginMessage(),
]);
}
登录时,查询失败,因为"email"不在"usuario",在"persona"
Unknown column 'email' in 'where clause' (SQL: select * from `usuario` where `email` = admin@localhost limit 1)
这不是更改数据库模型的解决方案,因为并非所有 "persona" 都是 "usuario",但所有 "usuario" 都是 "persona"。
尝试设置关系:
class Persona extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{....}
public function usuario()
{
return $this->hasOne('App\Usuario');
}
//----------------------------------------------------//
class Usuario extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
{....}
public function persona()
{
return $this->hasOne('App\Persona');
}
两个表具有相同的键。
但是查询没有改变,我想也许 Laravel 可以在某处创建一个 "INNER JOIN",不知道 Laravel 是否可以自动完成,所以我尝试了更改查询但不知道具体位置。
我想过这样的解决方案,但看起来太容易了,不知道是否是个好方法=/
- 从 post 获取 EMAIL 和 PASSWD
- 使用SQL 从BD获取ID、EMAIL和PASSWD
- 如果[EMAIL 和 PASSWD 匹配] Auth::loginUsingId(ID); [ELSE] Return 有错误。
据我所知,Auth::loginUsingId(ID);就像一个成功的 Auth::attempt()...但是有了这个解决方案,我需要知道如何分别实现以后的 Throttles 和 "remember" 选项...欢迎所有想法:D
我找到了一个解决方案:更改了 postLogin() 但在 AuthController 内部,因此我可以保留 Throttles 和 Remember 功能,并且核心仍然不变,如果我可以帮助其他人,请使用以下代码:
//------------------------------------
// Auth\AuthController.php
//------------------------------------
protected function postLogin(Request $request)
{
$this->validate($request, [
$this->loginUsername() => 'required', 'password' => 'required',
]);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $this->hasTooManyLoginAttempts($request)) {
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
//Here's the custom SQL, so you can retrieve a "user" and "pass" from anywhere in the DB
$usuario = \DB::select('
SELECT
persona.nombre,
usuario.password
FROM
persona
INNER JOIN
usuario ON persona.id_persona = usuario.id_persona
WHERE
persona.email = ?
LIMIT 1', array($credentials['email']));
// Instead of:
// if (Auth::attempt($credentials, $request->has('remember'))) {
if ($usuario && Hash::check($credentials['password'], $usuario[0]->password)) {
Auth::loginUsingId($usuario[0]->id_persona, $request->has('remember'));
// Put any custom data you need for the user/session
Session::put('nombre', $usuario[0]->nombre);
return $this->handleUserWasAuthenticated($request, $throttles);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
if ($throttles) {
$this->incrementLoginAttempts($request);
}
return redirect($this->loginPath())
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors([
$this->loginUsername() => $this->getFailedLoginMessage(),
]);
}